]> git.openfabrics.org - ~emulex/compat-rdma_3.12.git/commitdiff
Remove linux-next-cherry-picks patches
authorVladimir Sokolovsky <vlad@mellanox.com>
Sun, 17 Jun 2012 15:17:38 +0000 (18:17 +0300)
committerVladimir Sokolovsky <vlad@mellanox.com>
Sun, 17 Jun 2012 15:17:38 +0000 (18:17 +0300)
These patches are applied in kernel 3.5

Signed-off-by: Vladimir Sokolovsky <vlad@mellanox.com>
linux-next-cherry-picks/01-cxgb4-Detect-DB-FULL-events-and-notify-RDMA-ULD.patch [deleted file]
linux-next-cherry-picks/02-cxgb4-Common-platform-specific-changes-for-DB-Drop-R.patch [deleted file]
linux-next-cherry-picks/03-cxgb4-DB-Drop-Recovery-for-RDMA-and-LLD-queues.patch [deleted file]
linux-next-cherry-picks/04-RDMA-cxgb4-Add-debugfs-RDMA-memory-stats.patch [deleted file]
linux-next-cherry-picks/05-RDMA-cxgb4-Add-DB-Overflow-Avoidance.patch [deleted file]
linux-next-cherry-picks/06-RDMA-cxgb4-Disable-interrupts-in-c4iw_ev_dispatch.patch [deleted file]
linux-next-cherry-picks/07-RDMA-cxgb4-DB-Drop-Recovery-for-RDMA-and-LLD-queues.patch [deleted file]
linux-next-cherry-picks/08-RDMA-cxgb4-Use-vmalloc-for-debugfs-QP-dump.patch [deleted file]
linux-next-cherry-picks/09-RDMA-cxgb4-Remove-kfifo-usage.patch [deleted file]
linux-next-cherry-picks/10-RDMA-cxgb4-Add-query_qp-support.patch [deleted file]
linux-next-cherry-picks/11-IB-mlx4-pass-SMP-vendor-specific-attribute-MADs-to-f.patch [deleted file]

diff --git a/linux-next-cherry-picks/01-cxgb4-Detect-DB-FULL-events-and-notify-RDMA-ULD.patch b/linux-next-cherry-picks/01-cxgb4-Detect-DB-FULL-events-and-notify-RDMA-ULD.patch
deleted file mode 100644 (file)
index 576abdb..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-From 881806bc155c0d5d78196c8bfae0ea2e76ae7386 Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:24 +0530
-Subject: [PATCH 04/13] cxgb4: Detect DB FULL events and notify RDMA ULD
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h      |    4 +
- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |   77 +++++++++++++++++++++++
- drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h  |    7 ++
- drivers/net/ethernet/chelsio/cxgb4/sge.c        |    6 ++
- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c      |    9 +++
- 5 files changed, 103 insertions(+), 0 deletions(-)
-
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
-index 0fe1885..f91b259 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
-+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
-@@ -504,6 +504,8 @@ struct adapter {
-       void **tid_release_head;
-       spinlock_t tid_release_lock;
-       struct work_struct tid_release_task;
-+      struct work_struct db_full_task;
-+      struct work_struct db_drop_task;
-       bool tid_release_task_busy;
-
-       struct dentry *debugfs_root;
-@@ -719,4 +721,6 @@ int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
- int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
-                   unsigned int vf, unsigned int eqid);
- int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
-+void t4_db_full(struct adapter *adapter);
-+void t4_db_dropped(struct adapter *adapter);
- #endif /* __CXGB4_H__ */
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
-index b126b98..c243f93 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
-+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
-@@ -2366,6 +2366,16 @@ unsigned int cxgb4_port_chan(const struct net_device *dev)
- }
- EXPORT_SYMBOL(cxgb4_port_chan);
-
-+unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo)
-+{
-+      struct adapter *adap = netdev2adap(dev);
-+      u32 v;
-+
-+      v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
-+      return lpfifo ? G_LP_COUNT(v) : G_HP_COUNT(v);
-+}
-+EXPORT_SYMBOL(cxgb4_dbfifo_count);
-+
- /**
-  *    cxgb4_port_viid - get the VI id of a port
-  *    @dev: the net device for the port
-@@ -2446,6 +2456,69 @@ static struct notifier_block cxgb4_netevent_nb = {
-       .notifier_call = netevent_cb
- };
-
-+static void notify_rdma_uld(struct adapter *adap, enum cxgb4_control cmd)
-+{
-+      mutex_lock(&uld_mutex);
-+      if (adap->uld_handle[CXGB4_ULD_RDMA])
-+              ulds[CXGB4_ULD_RDMA].control(adap->uld_handle[CXGB4_ULD_RDMA],
-+                              cmd);
-+      mutex_unlock(&uld_mutex);
-+}
-+
-+static void process_db_full(struct work_struct *work)
-+{
-+      struct adapter *adap;
-+      static int delay = 1000;
-+      u32 v;
-+
-+      adap = container_of(work, struct adapter, db_full_task);
-+
-+
-+      /* stop LLD queues */
-+
-+      notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL);
-+      do {
-+              set_current_state(TASK_UNINTERRUPTIBLE);
-+              schedule_timeout(usecs_to_jiffies(delay));
-+              v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
-+              if (G_LP_COUNT(v) == 0 && G_HP_COUNT(v) == 0)
-+                      break;
-+      } while (1);
-+      notify_rdma_uld(adap, CXGB4_CONTROL_DB_EMPTY);
-+
-+
-+      /*
-+       * The more we get db full interrupts, the more we'll delay
-+       * in re-enabling db rings on queues, capped off at 200ms.
-+       */
-+      delay = min(delay << 1, 200000);
-+
-+      /* resume LLD queues */
-+}
-+
-+static void process_db_drop(struct work_struct *work)
-+{
-+      struct adapter *adap;
-+      adap = container_of(work, struct adapter, db_drop_task);
-+
-+
-+      /*
-+       * sync the PIDX values in HW and SW for LLD queues.
-+       */
-+
-+      notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP);
-+}
-+
-+void t4_db_full(struct adapter *adap)
-+{
-+      schedule_work(&adap->db_full_task);
-+}
-+
-+void t4_db_dropped(struct adapter *adap)
-+{
-+      schedule_work(&adap->db_drop_task);
-+}
-+
- static void uld_attach(struct adapter *adap, unsigned int uld)
- {
-       void *handle;
-@@ -2649,6 +2722,8 @@ static void cxgb_down(struct adapter *adapter)
- {
-       t4_intr_disable(adapter);
-       cancel_work_sync(&adapter->tid_release_task);
-+      cancel_work_sync(&adapter->db_full_task);
-+      cancel_work_sync(&adapter->db_drop_task);
-       adapter->tid_release_task_busy = false;
-       adapter->tid_release_head = NULL;
-
-@@ -3601,6 +3676,8 @@ static int __devinit init_one(struct pci_dev *pdev,
-       spin_lock_init(&adapter->tid_release_lock);
-
-       INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
-+      INIT_WORK(&adapter->db_full_task, process_db_full);
-+      INIT_WORK(&adapter->db_drop_task, process_db_drop);
-
-       err = t4_prep_adapter(adapter);
-       if (err)
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
-index b1d39b8..5cc2f27 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
-+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
-@@ -163,6 +163,12 @@ enum cxgb4_state {
-       CXGB4_STATE_DETACH
- };
-
-+enum cxgb4_control {
-+      CXGB4_CONTROL_DB_FULL,
-+      CXGB4_CONTROL_DB_EMPTY,
-+      CXGB4_CONTROL_DB_DROP,
-+};
-+
- struct pci_dev;
- struct l2t_data;
- struct net_device;
-@@ -225,6 +231,7 @@ struct cxgb4_uld_info {
- int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
- int cxgb4_unregister_uld(enum cxgb4_uld type);
- int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
-+unsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo);
- unsigned int cxgb4_port_chan(const struct net_device *dev);
- unsigned int cxgb4_port_viid(const struct net_device *dev);
- unsigned int cxgb4_port_idx(const struct net_device *dev);
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
-index 2dae795..234c157 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
-+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
-@@ -2415,6 +2415,12 @@ void t4_sge_init(struct adapter *adap)
-                        RXPKTCPLMODE |
-                        (STAT_LEN == 128 ? EGRSTATUSPAGESIZE : 0));
-
-+      t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS,
-+                      V_HP_INT_THRESH(5) | V_LP_INT_THRESH(5),
-+                      V_HP_INT_THRESH(5) | V_LP_INT_THRESH(5));
-+      t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_ENABLE_DROP,
-+                      F_ENABLE_DROP);
-+
-       for (i = v = 0; i < 32; i += 4)
-               v |= (PAGE_SHIFT - 10) << i;
-       t4_write_reg(adap, SGE_HOST_PAGE_SIZE, v);
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
-index d1ec111..13609bf 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
-+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
-@@ -1013,6 +1013,8 @@ static void sge_intr_handler(struct adapter *adapter)
-               { ERR_INVALID_CIDX_INC,
-                 "SGE GTS CIDX increment too large", -1, 0 },
-               { ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 },
-+              { F_DBFIFO_LP_INT, NULL, -1, 0 },
-+              { F_DBFIFO_HP_INT, NULL, -1, 0 },
-               { ERR_DROPPED_DB, "SGE doorbell dropped", -1, 0 },
-               { ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0,
-                 "SGE IQID > 1023 received CPL for FL", -1, 0 },
-@@ -1042,6 +1044,12 @@ static void sge_intr_handler(struct adapter *adapter)
-               t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32);
-       }
-
-+      err = t4_read_reg(adapter, A_SGE_INT_CAUSE3);
-+      if (err & (F_DBFIFO_HP_INT|F_DBFIFO_LP_INT))
-+              t4_db_full(adapter);
-+      if (err & F_ERR_DROPPED_DB)
-+              t4_db_dropped(adapter);
-+
-       if (t4_handle_intr_status(adapter, SGE_INT_CAUSE3, sge_intr_info) ||
-           v != 0)
-               t4_fatal_err(adapter);
-@@ -1513,6 +1521,7 @@ void t4_intr_enable(struct adapter *adapter)
-                    ERR_BAD_DB_PIDX2 | ERR_BAD_DB_PIDX1 |
-                    ERR_BAD_DB_PIDX0 | ERR_ING_CTXT_PRIO |
-                    ERR_EGR_CTXT_PRIO | INGRESS_SIZE_ERR |
-+                   F_DBFIFO_HP_INT | F_DBFIFO_LP_INT |
-                    EGRESS_SIZE_ERR);
-       t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE), PF_INTR_MASK);
-       t4_set_reg_field(adapter, PL_INT_MAP0, 0, 1 << pf);
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/02-cxgb4-Common-platform-specific-changes-for-DB-Drop-R.patch b/linux-next-cherry-picks/02-cxgb4-Common-platform-specific-changes-for-DB-Drop-R.patch
deleted file mode 100644 (file)
index 7389bf6..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-From 8caa1e8446948afefdb4dd2050a465f6da777652 Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:25 +0530
-Subject: [PATCH 05/13] cxgb4: Common platform specific changes for DB Drop Recovery
-
-Add platform-specific callback functions for interrupts.  This is
-needed to do a single read-clear of the CAUSE register and then call
-out to platform specific functions for DB threshold interrupts and DB
-drop interrupts.
-
-Add t4_mem_win_read_len() - mem-window reads for arbitrary lengths.
-This is used to read the CIDX/PIDX values from EC contexts during DB
-drop recovery.
-
-Add t4_fwaddrspace_write() - sends addrspace write cmds to the fw.
-Needed to flush the sge eq context cache.
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |    3 +
- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c |   69 +++++++++++++++++++++++----
- 2 files changed, 61 insertions(+), 11 deletions(-)
-
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
-index f91b259..5f3c0a7 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
-+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
-@@ -723,4 +723,7 @@ int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
- int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl);
- void t4_db_full(struct adapter *adapter);
- void t4_db_dropped(struct adapter *adapter);
-+int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len);
-+int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
-+                       u32 addr, u32 val);
- #endif /* __CXGB4_H__ */
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
-index 13609bf..32e1dd5 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
-+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
-@@ -868,11 +868,14 @@ int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port)
-       return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
- }
-
-+typedef void (*int_handler_t)(struct adapter *adap);
-+
- struct intr_info {
-       unsigned int mask;       /* bits to check in interrupt status */
-       const char *msg;         /* message to print or NULL */
-       short stat_idx;          /* stat counter to increment or -1 */
-       unsigned short fatal;    /* whether the condition reported is fatal */
-+      int_handler_t int_handler; /* platform-specific int handler */
- };
-
- /**
-@@ -905,6 +908,8 @@ static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
-               } else if (acts->msg && printk_ratelimit())
-                       dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
-                                status & acts->mask);
-+              if (acts->int_handler)
-+                      acts->int_handler(adapter);
-               mask |= acts->mask;
-       }
-       status &= mask;
-@@ -1013,9 +1018,9 @@ static void sge_intr_handler(struct adapter *adapter)
-               { ERR_INVALID_CIDX_INC,
-                 "SGE GTS CIDX increment too large", -1, 0 },
-               { ERR_CPL_OPCODE_0, "SGE received 0-length CPL", -1, 0 },
--              { F_DBFIFO_LP_INT, NULL, -1, 0 },
--              { F_DBFIFO_HP_INT, NULL, -1, 0 },
--              { ERR_DROPPED_DB, "SGE doorbell dropped", -1, 0 },
-+              { F_DBFIFO_LP_INT, NULL, -1, 0, t4_db_full },
-+              { F_DBFIFO_HP_INT, NULL, -1, 0, t4_db_full },
-+              { F_ERR_DROPPED_DB, NULL, -1, 0, t4_db_dropped },
-               { ERR_DATA_CPL_ON_HIGH_QID1 | ERR_DATA_CPL_ON_HIGH_QID0,
-                 "SGE IQID > 1023 received CPL for FL", -1, 0 },
-               { ERR_BAD_DB_PIDX3, "SGE DBP 3 pidx increment too large", -1,
-@@ -1036,20 +1041,14 @@ static void sge_intr_handler(struct adapter *adapter)
-       };
-
-       v = (u64)t4_read_reg(adapter, SGE_INT_CAUSE1) |
--          ((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32);
-+              ((u64)t4_read_reg(adapter, SGE_INT_CAUSE2) << 32);
-       if (v) {
-               dev_alert(adapter->pdev_dev, "SGE parity error (%#llx)\n",
--                       (unsigned long long)v);
-+                              (unsigned long long)v);
-               t4_write_reg(adapter, SGE_INT_CAUSE1, v);
-               t4_write_reg(adapter, SGE_INT_CAUSE2, v >> 32);
-       }
-
--      err = t4_read_reg(adapter, A_SGE_INT_CAUSE3);
--      if (err & (F_DBFIFO_HP_INT|F_DBFIFO_LP_INT))
--              t4_db_full(adapter);
--      if (err & F_ERR_DROPPED_DB)
--              t4_db_dropped(adapter);
--
-       if (t4_handle_intr_status(adapter, SGE_INT_CAUSE3, sge_intr_info) ||
-           v != 0)
-               t4_fatal_err(adapter);
-@@ -1995,6 +1994,54 @@ int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
-       (var).retval_len16 = htonl(FW_LEN16(var)); \
- } while (0)
-
-+int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
-+                        u32 addr, u32 val)
-+{
-+      struct fw_ldst_cmd c;
-+
-+      memset(&c, 0, sizeof(c));
-+      c.op_to_addrspace = htonl(V_FW_CMD_OP(FW_LDST_CMD) | F_FW_CMD_REQUEST |
-+                          F_FW_CMD_WRITE |
-+                          V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FIRMWARE));
-+      c.cycles_to_len16 = htonl(FW_LEN16(c));
-+      c.u.addrval.addr = htonl(addr);
-+      c.u.addrval.val = htonl(val);
-+
-+      return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
-+}
-+
-+/*
-+ *     t4_mem_win_read_len - read memory through PCIE memory window
-+ *     @adap: the adapter
-+ *     @addr: address of first byte requested aligned on 32b.
-+ *     @data: len bytes to hold the data read
-+ *     @len: amount of data to read from window.  Must be <=
-+ *            MEMWIN0_APERATURE after adjusting for 16B alignment
-+ *            requirements of the the memory window.
-+ *
-+ *     Read len bytes of data from MC starting at @addr.
-+ */
-+int t4_mem_win_read_len(struct adapter *adap, u32 addr, __be32 *data, int len)
-+{
-+      int i;
-+      int off;
-+
-+      /*
-+       * Align on a 16B boundary.
-+       */
-+      off = addr & 15;
-+      if ((addr & 3) || (len + off) > MEMWIN0_APERTURE)
-+              return -EINVAL;
-+
-+      t4_write_reg(adap, A_PCIE_MEM_ACCESS_OFFSET, addr & ~15);
-+      t4_read_reg(adap, A_PCIE_MEM_ACCESS_OFFSET);
-+
-+      for (i = 0; i < len; i += 4)
-+              *data++ = t4_read_reg(adap, (MEMWIN0_BASE + off + i));
-+
-+      return 0;
-+}
-+
- /**
-  *    t4_mdio_rd - read a PHY register through MDIO
-  *    @adap: the adapter
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/03-cxgb4-DB-Drop-Recovery-for-RDMA-and-LLD-queues.patch b/linux-next-cherry-picks/03-cxgb4-DB-Drop-Recovery-for-RDMA-and-LLD-queues.patch
deleted file mode 100644 (file)
index b0c4640..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-From 3069ee9bc451d90a2fa8c3c7ef2774744d9d3bb0 Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:26 +0530
-Subject: [PATCH 06/13] cxgb4: DB Drop Recovery for RDMA and LLD queues
-
-recover LLD EQs for DB drop interrupts.  This includes adding a new
-db_lock, a spin lock disabling BH too, used by the recovery thread and
-the ring_tx_db() paths to allow db drop recovery.
-
-Clean up initial DB avoidance code.
-
-Add read_eq_indices() - this allows the LLD to use the PCIe mw to
-efficiently read hw eq contexts.
-
-Add cxgb4_sync_txq_pidx() - called by iw_cxgb4 to sync up the sw/hw
-pidx value.
-
-Add flush_eq_cache() and cxgb4_flush_eq_cache().  This allows iw_cxgb4
-to flush the sge eq context cache before beginning db drop recovery.
-
-Add module parameter, dbfoifo_int_thresh, to allow tuning the db
-interrupt threshold value.
-
-Add dbfifo_int_thresh to cxgb4_lld_info so iw_cxgb4 knows the threshold.
-
-Add module parameter, dbfoifo_drain_delay, to allow tuning the amount
-of time delay between DB FULL and EMPTY upcalls to iw_cxgb4.
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/net/ethernet/chelsio/cxgb4/cxgb4.h      |   16 ++
- drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c |  214 +++++++++++++++++++----
- drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h  |    4 +
- drivers/net/ethernet/chelsio/cxgb4/sge.c        |   20 ++-
- drivers/net/ethernet/chelsio/cxgb4/t4_regs.h    |   53 ++++++
- drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h   |   15 ++
- 6 files changed, 280 insertions(+), 42 deletions(-)
-
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
-index 5f3c0a7..ec2dafe 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
-+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
-@@ -51,6 +51,8 @@
- #define FW_VERSION_MINOR 1
- #define FW_VERSION_MICRO 0
-
-+#define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__)
-+
- enum {
-       MAX_NPORTS = 4,     /* max # of ports */
-       SERNUM_LEN = 24,    /* Serial # length */
-@@ -64,6 +66,15 @@ enum {
-       MEM_MC
- };
-
-+enum {
-+      MEMWIN0_APERTURE = 65536,
-+      MEMWIN0_BASE     = 0x30000,
-+      MEMWIN1_APERTURE = 32768,
-+      MEMWIN1_BASE     = 0x28000,
-+      MEMWIN2_APERTURE = 2048,
-+      MEMWIN2_BASE     = 0x1b800,
-+};
-+
- enum dev_master {
-       MASTER_CANT,
-       MASTER_MAY,
-@@ -403,6 +414,9 @@ struct sge_txq {
-       struct tx_sw_desc *sdesc;   /* address of SW Tx descriptor ring */
-       struct sge_qstat *stat;     /* queue status entry */
-       dma_addr_t    phys_addr;    /* physical address of the ring */
-+      spinlock_t db_lock;
-+      int db_disabled;
-+      unsigned short db_pidx;
- };
-
- struct sge_eth_txq {                /* state for an SGE Ethernet Tx queue */
-@@ -475,6 +489,7 @@ struct adapter {
-       void __iomem *regs;
-       struct pci_dev *pdev;
-       struct device *pdev_dev;
-+      unsigned int mbox;
-       unsigned int fn;
-       unsigned int flags;
-
-@@ -607,6 +622,7 @@ irqreturn_t t4_sge_intr_msix(int irq, void *cookie);
- void t4_sge_init(struct adapter *adap);
- void t4_sge_start(struct adapter *adap);
- void t4_sge_stop(struct adapter *adap);
-+extern int dbfifo_int_thresh;
-
- #define for_each_port(adapter, iter) \
-       for (iter = 0; iter < (adapter)->params.nports; ++iter)
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
-index c243f93..e1f96fb 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
-+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
-@@ -149,15 +149,6 @@ static unsigned int pfvfres_pmask(struct adapter *adapter,
- #endif
-
- enum {
--      MEMWIN0_APERTURE = 65536,
--      MEMWIN0_BASE     = 0x30000,
--      MEMWIN1_APERTURE = 32768,
--      MEMWIN1_BASE     = 0x28000,
--      MEMWIN2_APERTURE = 2048,
--      MEMWIN2_BASE     = 0x1b800,
--};
--
--enum {
-       MAX_TXQ_ENTRIES      = 16384,
-       MAX_CTRL_TXQ_ENTRIES = 1024,
-       MAX_RSPQ_ENTRIES     = 16384,
-@@ -371,6 +362,15 @@ static int set_addr_filters(const struct net_device *dev, bool sleep)
-                               uhash | mhash, sleep);
- }
-
-+int dbfifo_int_thresh = 10; /* 10 == 640 entry threshold */
-+module_param(dbfifo_int_thresh, int, 0644);
-+MODULE_PARM_DESC(dbfifo_int_thresh, "doorbell fifo interrupt threshold");
-+
-+int dbfifo_drain_delay = 1000; /* usecs to sleep while draining the dbfifo */
-+module_param(dbfifo_drain_delay, int, 0644);
-+MODULE_PARM_DESC(dbfifo_drain_delay,
-+               "usecs to sleep while draining the dbfifo");
-+
- /*
-  * Set Rx properties of a port, such as promiscruity, address filters, and MTU.
-  * If @mtu is -1 it is left unchanged.
-@@ -389,6 +389,8 @@ static int set_rxmode(struct net_device *dev, int mtu, bool sleep_ok)
-       return ret;
- }
-
-+static struct workqueue_struct *workq;
-+
- /**
-  *    link_start - enable a port
-  *    @dev: the port to enable
-@@ -2196,7 +2198,7 @@ static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan,
-       adap->tid_release_head = (void **)((uintptr_t)p | chan);
-       if (!adap->tid_release_task_busy) {
-               adap->tid_release_task_busy = true;
--              schedule_work(&adap->tid_release_task);
-+              queue_work(workq, &adap->tid_release_task);
-       }
-       spin_unlock_bh(&adap->tid_release_lock);
- }
-@@ -2423,6 +2425,59 @@ void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
- }
- EXPORT_SYMBOL(cxgb4_iscsi_init);
-
-+int cxgb4_flush_eq_cache(struct net_device *dev)
-+{
-+      struct adapter *adap = netdev2adap(dev);
-+      int ret;
-+
-+      ret = t4_fwaddrspace_write(adap, adap->mbox,
-+                                 0xe1000000 + A_SGE_CTXT_CMD, 0x20000000);
-+      return ret;
-+}
-+EXPORT_SYMBOL(cxgb4_flush_eq_cache);
-+
-+static int read_eq_indices(struct adapter *adap, u16 qid, u16 *pidx, u16 *cidx)
-+{
-+      u32 addr = t4_read_reg(adap, A_SGE_DBQ_CTXT_BADDR) + 24 * qid + 8;
-+      __be64 indices;
-+      int ret;
-+
-+      ret = t4_mem_win_read_len(adap, addr, (__be32 *)&indices, 8);
-+      if (!ret) {
-+              indices = be64_to_cpu(indices);
-+              *cidx = (indices >> 25) & 0xffff;
-+              *pidx = (indices >> 9) & 0xffff;
-+      }
-+      return ret;
-+}
-+
-+int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx,
-+                      u16 size)
-+{
-+      struct adapter *adap = netdev2adap(dev);
-+      u16 hw_pidx, hw_cidx;
-+      int ret;
-+
-+      ret = read_eq_indices(adap, qid, &hw_pidx, &hw_cidx);
-+      if (ret)
-+              goto out;
-+
-+      if (pidx != hw_pidx) {
-+              u16 delta;
-+
-+              if (pidx >= hw_pidx)
-+                      delta = pidx - hw_pidx;
-+              else
-+                      delta = size - hw_pidx + pidx;
-+              wmb();
-+              t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
-+                           V_QID(qid) | V_PIDX(delta));
-+      }
-+out:
-+      return ret;
-+}
-+EXPORT_SYMBOL(cxgb4_sync_txq_pidx);
-+
- static struct pci_driver cxgb4_driver;
-
- static void check_neigh_update(struct neighbour *neigh)
-@@ -2456,6 +2511,95 @@ static struct notifier_block cxgb4_netevent_nb = {
-       .notifier_call = netevent_cb
- };
-
-+static void drain_db_fifo(struct adapter *adap, int usecs)
-+{
-+      u32 v;
-+
-+      do {
-+              set_current_state(TASK_UNINTERRUPTIBLE);
-+              schedule_timeout(usecs_to_jiffies(usecs));
-+              v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
-+              if (G_LP_COUNT(v) == 0 && G_HP_COUNT(v) == 0)
-+                      break;
-+      } while (1);
-+}
-+
-+static void disable_txq_db(struct sge_txq *q)
-+{
-+      spin_lock_irq(&q->db_lock);
-+      q->db_disabled = 1;
-+      spin_unlock_irq(&q->db_lock);
-+}
-+
-+static void enable_txq_db(struct sge_txq *q)
-+{
-+      spin_lock_irq(&q->db_lock);
-+      q->db_disabled = 0;
-+      spin_unlock_irq(&q->db_lock);
-+}
-+
-+static void disable_dbs(struct adapter *adap)
-+{
-+      int i;
-+
-+      for_each_ethrxq(&adap->sge, i)
-+              disable_txq_db(&adap->sge.ethtxq[i].q);
-+      for_each_ofldrxq(&adap->sge, i)
-+              disable_txq_db(&adap->sge.ofldtxq[i].q);
-+      for_each_port(adap, i)
-+              disable_txq_db(&adap->sge.ctrlq[i].q);
-+}
-+
-+static void enable_dbs(struct adapter *adap)
-+{
-+      int i;
-+
-+      for_each_ethrxq(&adap->sge, i)
-+              enable_txq_db(&adap->sge.ethtxq[i].q);
-+      for_each_ofldrxq(&adap->sge, i)
-+              enable_txq_db(&adap->sge.ofldtxq[i].q);
-+      for_each_port(adap, i)
-+              enable_txq_db(&adap->sge.ctrlq[i].q);
-+}
-+
-+static void sync_txq_pidx(struct adapter *adap, struct sge_txq *q)
-+{
-+      u16 hw_pidx, hw_cidx;
-+      int ret;
-+
-+      spin_lock_bh(&q->db_lock);
-+      ret = read_eq_indices(adap, (u16)q->cntxt_id, &hw_pidx, &hw_cidx);
-+      if (ret)
-+              goto out;
-+      if (q->db_pidx != hw_pidx) {
-+              u16 delta;
-+
-+              if (q->db_pidx >= hw_pidx)
-+                      delta = q->db_pidx - hw_pidx;
-+              else
-+                      delta = q->size - hw_pidx + q->db_pidx;
-+              wmb();
-+              t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
-+                              V_QID(q->cntxt_id) | V_PIDX(delta));
-+      }
-+out:
-+      q->db_disabled = 0;
-+      spin_unlock_bh(&q->db_lock);
-+      if (ret)
-+              CH_WARN(adap, "DB drop recovery failed.\n");
-+}
-+static void recover_all_queues(struct adapter *adap)
-+{
-+      int i;
-+
-+      for_each_ethrxq(&adap->sge, i)
-+              sync_txq_pidx(adap, &adap->sge.ethtxq[i].q);
-+      for_each_ofldrxq(&adap->sge, i)
-+              sync_txq_pidx(adap, &adap->sge.ofldtxq[i].q);
-+      for_each_port(adap, i)
-+              sync_txq_pidx(adap, &adap->sge.ctrlq[i].q);
-+}
-+
- static void notify_rdma_uld(struct adapter *adap, enum cxgb4_control cmd)
- {
-       mutex_lock(&uld_mutex);
-@@ -2468,55 +2612,41 @@ static void notify_rdma_uld(struct adapter *adap, enum cxgb4_control cmd)
- static void process_db_full(struct work_struct *work)
- {
-       struct adapter *adap;
--      static int delay = 1000;
--      u32 v;
-
-       adap = container_of(work, struct adapter, db_full_task);
-
--
--      /* stop LLD queues */
--
-       notify_rdma_uld(adap, CXGB4_CONTROL_DB_FULL);
--      do {
--              set_current_state(TASK_UNINTERRUPTIBLE);
--              schedule_timeout(usecs_to_jiffies(delay));
--              v = t4_read_reg(adap, A_SGE_DBFIFO_STATUS);
--              if (G_LP_COUNT(v) == 0 && G_HP_COUNT(v) == 0)
--                      break;
--      } while (1);
-+      drain_db_fifo(adap, dbfifo_drain_delay);
-+      t4_set_reg_field(adap, A_SGE_INT_ENABLE3,
-+                      F_DBFIFO_HP_INT | F_DBFIFO_LP_INT,
-+                      F_DBFIFO_HP_INT | F_DBFIFO_LP_INT);
-       notify_rdma_uld(adap, CXGB4_CONTROL_DB_EMPTY);
--
--
--      /*
--       * The more we get db full interrupts, the more we'll delay
--       * in re-enabling db rings on queues, capped off at 200ms.
--       */
--      delay = min(delay << 1, 200000);
--
--      /* resume LLD queues */
- }
-
- static void process_db_drop(struct work_struct *work)
- {
-       struct adapter *adap;
--      adap = container_of(work, struct adapter, db_drop_task);
-
-+      adap = container_of(work, struct adapter, db_drop_task);
-
--      /*
--       * sync the PIDX values in HW and SW for LLD queues.
--       */
--
-+      t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_DROPPED_DB, 0);
-+      disable_dbs(adap);
-       notify_rdma_uld(adap, CXGB4_CONTROL_DB_DROP);
-+      drain_db_fifo(adap, 1);
-+      recover_all_queues(adap);
-+      enable_dbs(adap);
- }
-
- void t4_db_full(struct adapter *adap)
- {
--      schedule_work(&adap->db_full_task);
-+      t4_set_reg_field(adap, A_SGE_INT_ENABLE3,
-+                      F_DBFIFO_HP_INT | F_DBFIFO_LP_INT, 0);
-+      queue_work(workq, &adap->db_full_task);
- }
-
- void t4_db_dropped(struct adapter *adap)
- {
--      schedule_work(&adap->db_drop_task);
-+      queue_work(workq, &adap->db_drop_task);
- }
-
- static void uld_attach(struct adapter *adap, unsigned int uld)
-@@ -2552,6 +2682,7 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
-       lli.gts_reg = adap->regs + MYPF_REG(SGE_PF_GTS);
-       lli.db_reg = adap->regs + MYPF_REG(SGE_PF_KDOORBELL);
-       lli.fw_vers = adap->params.fw_vers;
-+      lli.dbfifo_int_thresh = dbfifo_int_thresh;
-
-       handle = ulds[uld].add(&lli);
-       if (IS_ERR(handle)) {
-@@ -3668,6 +3799,7 @@ static int __devinit init_one(struct pci_dev *pdev,
-
-       adapter->pdev = pdev;
-       adapter->pdev_dev = &pdev->dev;
-+      adapter->mbox = func;
-       adapter->fn = func;
-       adapter->msg_enable = dflt_msg_enable;
-       memset(adapter->chan_map, 0xff, sizeof(adapter->chan_map));
-@@ -3865,6 +3997,10 @@ static int __init cxgb4_init_module(void)
- {
-       int ret;
-
-+      workq = create_singlethread_workqueue("cxgb4");
-+      if (!workq)
-+              return -ENOMEM;
-+
-       /* Debugfs support is optional, just warn if this fails */
-       cxgb4_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
-       if (!cxgb4_debugfs_root)
-@@ -3880,6 +4016,8 @@ static void __exit cxgb4_cleanup_module(void)
- {
-       pci_unregister_driver(&cxgb4_driver);
-       debugfs_remove(cxgb4_debugfs_root);  /* NULL ok */
-+      flush_workqueue(workq);
-+      destroy_workqueue(workq);
- }
-
- module_init(cxgb4_init_module);
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
-index 5cc2f27..d79980c 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
-+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
-@@ -218,6 +218,7 @@ struct cxgb4_lld_info {
-       unsigned short ucq_density;          /* # of user CQs/page */
-       void __iomem *gts_reg;               /* address of GTS register */
-       void __iomem *db_reg;                /* address of kernel doorbell */
-+      int dbfifo_int_thresh;               /* doorbell fifo int threshold */
- };
-
- struct cxgb4_uld_info {
-@@ -226,6 +227,7 @@ struct cxgb4_uld_info {
-       int (*rx_handler)(void *handle, const __be64 *rsp,
-                         const struct pkt_gl *gl);
-       int (*state_change)(void *handle, enum cxgb4_state new_state);
-+      int (*control)(void *handle, enum cxgb4_control control, ...);
- };
-
- int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
-@@ -243,4 +245,6 @@ void cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
-                     const unsigned int *pgsz_order);
- struct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
-                                  unsigned int skb_len, unsigned int pull_len);
-+int cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, u16 size);
-+int cxgb4_flush_eq_cache(struct net_device *dev);
- #endif  /* !__CXGB4_OFLD_H */
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
-index 234c157..e111d97 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
-+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
-@@ -767,8 +767,13 @@ static void write_sgl(const struct sk_buff *skb, struct sge_txq *q,
- static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q, int n)
- {
-       wmb();            /* write descriptors before telling HW */
--      t4_write_reg(adap, MYPF_REG(SGE_PF_KDOORBELL),
--                   QID(q->cntxt_id) | PIDX(n));
-+      spin_lock(&q->db_lock);
-+      if (!q->db_disabled) {
-+              t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
-+                           V_QID(q->cntxt_id) | V_PIDX(n));
-+      }
-+      q->db_pidx = q->pidx;
-+      spin_unlock(&q->db_lock);
- }
-
- /**
-@@ -2081,6 +2086,7 @@ static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
-       q->stops = q->restarts = 0;
-       q->stat = (void *)&q->desc[q->size];
-       q->cntxt_id = id;
-+      spin_lock_init(&q->db_lock);
-       adap->sge.egr_map[id - adap->sge.egr_start] = q;
- }
-
-@@ -2415,9 +2421,15 @@ void t4_sge_init(struct adapter *adap)
-                        RXPKTCPLMODE |
-                        (STAT_LEN == 128 ? EGRSTATUSPAGESIZE : 0));
-
-+      /*
-+       * Set up to drop DOORBELL writes when the DOORBELL FIFO overflows
-+       * and generate an interrupt when this occurs so we can recover.
-+       */
-       t4_set_reg_field(adap, A_SGE_DBFIFO_STATUS,
--                      V_HP_INT_THRESH(5) | V_LP_INT_THRESH(5),
--                      V_HP_INT_THRESH(5) | V_LP_INT_THRESH(5));
-+                      V_HP_INT_THRESH(M_HP_INT_THRESH) |
-+                      V_LP_INT_THRESH(M_LP_INT_THRESH),
-+                      V_HP_INT_THRESH(dbfifo_int_thresh) |
-+                      V_LP_INT_THRESH(dbfifo_int_thresh));
-       t4_set_reg_field(adap, A_SGE_DOORBELL_CONTROL, F_ENABLE_DROP,
-                       F_ENABLE_DROP);
-
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
-index 0adc5bc..111fc32 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
-+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
-@@ -190,6 +190,59 @@
- #define SGE_DEBUG_DATA_LOW 0x10d4
- #define SGE_INGRESS_QUEUES_PER_PAGE_PF 0x10f4
-
-+#define S_LP_INT_THRESH    12
-+#define V_LP_INT_THRESH(x) ((x) << S_LP_INT_THRESH)
-+#define S_HP_INT_THRESH    28
-+#define V_HP_INT_THRESH(x) ((x) << S_HP_INT_THRESH)
-+#define A_SGE_DBFIFO_STATUS 0x10a4
-+
-+#define S_ENABLE_DROP    13
-+#define V_ENABLE_DROP(x) ((x) << S_ENABLE_DROP)
-+#define F_ENABLE_DROP    V_ENABLE_DROP(1U)
-+#define A_SGE_DOORBELL_CONTROL 0x10a8
-+
-+#define A_SGE_CTXT_CMD 0x11fc
-+#define A_SGE_DBQ_CTXT_BADDR 0x1084
-+
-+#define A_SGE_PF_KDOORBELL 0x0
-+
-+#define S_QID 15
-+#define V_QID(x) ((x) << S_QID)
-+
-+#define S_PIDX 0
-+#define V_PIDX(x) ((x) << S_PIDX)
-+
-+#define M_LP_COUNT 0x7ffU
-+#define S_LP_COUNT 0
-+#define G_LP_COUNT(x) (((x) >> S_LP_COUNT) & M_LP_COUNT)
-+
-+#define M_HP_COUNT 0x7ffU
-+#define S_HP_COUNT 16
-+#define G_HP_COUNT(x) (((x) >> S_HP_COUNT) & M_HP_COUNT)
-+
-+#define A_SGE_INT_ENABLE3 0x1040
-+
-+#define S_DBFIFO_HP_INT 8
-+#define V_DBFIFO_HP_INT(x) ((x) << S_DBFIFO_HP_INT)
-+#define F_DBFIFO_HP_INT V_DBFIFO_HP_INT(1U)
-+
-+#define S_DBFIFO_LP_INT 7
-+#define V_DBFIFO_LP_INT(x) ((x) << S_DBFIFO_LP_INT)
-+#define F_DBFIFO_LP_INT V_DBFIFO_LP_INT(1U)
-+
-+#define S_DROPPED_DB 0
-+#define V_DROPPED_DB(x) ((x) << S_DROPPED_DB)
-+#define F_DROPPED_DB V_DROPPED_DB(1U)
-+
-+#define S_ERR_DROPPED_DB 18
-+#define V_ERR_DROPPED_DB(x) ((x) << S_ERR_DROPPED_DB)
-+#define F_ERR_DROPPED_DB V_ERR_DROPPED_DB(1U)
-+
-+#define A_PCIE_MEM_ACCESS_OFFSET 0x306c
-+
-+#define M_HP_INT_THRESH 0xfU
-+#define M_LP_INT_THRESH 0xfU
-+
- #define PCIE_PF_CLI 0x44
- #define PCIE_INT_CAUSE 0x3004
- #define  UNXSPLCPLERR  0x20000000U
-diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
-index edcfd7e..ad53f79 100644
---- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
-+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
-@@ -1620,4 +1620,19 @@ struct fw_hdr {
- #define FW_HDR_FW_VER_MINOR_GET(x) (((x) >> 16) & 0xff)
- #define FW_HDR_FW_VER_MICRO_GET(x) (((x) >> 8) & 0xff)
- #define FW_HDR_FW_VER_BUILD_GET(x) (((x) >> 0) & 0xff)
-+
-+#define S_FW_CMD_OP 24
-+#define V_FW_CMD_OP(x) ((x) << S_FW_CMD_OP)
-+
-+#define S_FW_CMD_REQUEST 23
-+#define V_FW_CMD_REQUEST(x) ((x) << S_FW_CMD_REQUEST)
-+#define F_FW_CMD_REQUEST V_FW_CMD_REQUEST(1U)
-+
-+#define S_FW_CMD_WRITE 21
-+#define V_FW_CMD_WRITE(x) ((x) << S_FW_CMD_WRITE)
-+#define F_FW_CMD_WRITE V_FW_CMD_WRITE(1U)
-+
-+#define S_FW_LDST_CMD_ADDRSPACE 0
-+#define V_FW_LDST_CMD_ADDRSPACE(x) ((x) << S_FW_LDST_CMD_ADDRSPACE)
-+
- #endif /* _T4FW_INTERFACE_H_ */
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/04-RDMA-cxgb4-Add-debugfs-RDMA-memory-stats.patch b/linux-next-cherry-picks/04-RDMA-cxgb4-Add-debugfs-RDMA-memory-stats.patch
deleted file mode 100644 (file)
index 2859793..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-From 8d81ef34b249109084b2f3c4bb826d0417ef5814 Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:27 +0530
-Subject: [PATCH 07/13] RDMA/cxgb4: Add debugfs RDMA memory stats
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/infiniband/hw/cxgb4/device.c   |   78 +++++++++++++++++++++++++++++++-
- drivers/infiniband/hw/cxgb4/iw_cxgb4.h |   17 +++++++
- drivers/infiniband/hw/cxgb4/mem.c      |   11 ++++-
- drivers/infiniband/hw/cxgb4/provider.c |    8 +++
- drivers/infiniband/hw/cxgb4/resource.c |   44 ++++++++++++++++++
- 5 files changed, 155 insertions(+), 3 deletions(-)
-
-diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
-index 6d0df6e..8483111 100644
---- a/drivers/infiniband/hw/cxgb4/device.c
-+++ b/drivers/infiniband/hw/cxgb4/device.c
-@@ -240,6 +240,62 @@ static const struct file_operations stag_debugfs_fops = {
-       .llseek  = default_llseek,
- };
-
-+static int stats_show(struct seq_file *seq, void *v)
-+{
-+      struct c4iw_dev *dev = seq->private;
-+
-+      seq_printf(seq, " Object: %10s %10s %10s\n", "Total", "Current", "Max");
-+      seq_printf(seq, "     PDID: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.pd.total, dev->rdev.stats.pd.cur,
-+                      dev->rdev.stats.pd.max);
-+      seq_printf(seq, "      QID: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.qid.total, dev->rdev.stats.qid.cur,
-+                      dev->rdev.stats.qid.max);
-+      seq_printf(seq, "   TPTMEM: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.stag.total, dev->rdev.stats.stag.cur,
-+                      dev->rdev.stats.stag.max);
-+      seq_printf(seq, "   PBLMEM: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.pbl.total, dev->rdev.stats.pbl.cur,
-+                      dev->rdev.stats.pbl.max);
-+      seq_printf(seq, "   RQTMEM: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.rqt.total, dev->rdev.stats.rqt.cur,
-+                      dev->rdev.stats.rqt.max);
-+      seq_printf(seq, "  OCQPMEM: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.ocqp.total, dev->rdev.stats.ocqp.cur,
-+                      dev->rdev.stats.ocqp.max);
-+      return 0;
-+}
-+
-+static int stats_open(struct inode *inode, struct file *file)
-+{
-+      return single_open(file, stats_show, inode->i_private);
-+}
-+
-+static ssize_t stats_clear(struct file *file, const char __user *buf,
-+              size_t count, loff_t *pos)
-+{
-+      struct c4iw_dev *dev = ((struct seq_file *)file->private_data)->private;
-+
-+      mutex_lock(&dev->rdev.stats.lock);
-+      dev->rdev.stats.pd.max = 0;
-+      dev->rdev.stats.qid.max = 0;
-+      dev->rdev.stats.stag.max = 0;
-+      dev->rdev.stats.pbl.max = 0;
-+      dev->rdev.stats.rqt.max = 0;
-+      dev->rdev.stats.ocqp.max = 0;
-+      mutex_unlock(&dev->rdev.stats.lock);
-+      return count;
-+}
-+
-+static const struct file_operations stats_debugfs_fops = {
-+      .owner   = THIS_MODULE,
-+      .open    = stats_open,
-+      .release = single_release,
-+      .read    = seq_read,
-+      .llseek  = seq_lseek,
-+      .write   = stats_clear,
-+};
-+
- static int setup_debugfs(struct c4iw_dev *devp)
- {
-       struct dentry *de;
-@@ -256,6 +312,12 @@ static int setup_debugfs(struct c4iw_dev *devp)
-                                (void *)devp, &stag_debugfs_fops);
-       if (de && de->d_inode)
-               de->d_inode->i_size = 4096;
-+
-+      de = debugfs_create_file("stats", S_IWUSR, devp->debugfs_root,
-+                      (void *)devp, &stats_debugfs_fops);
-+      if (de && de->d_inode)
-+              de->d_inode->i_size = 4096;
-+
-       return 0;
- }
-
-@@ -269,9 +331,13 @@ void c4iw_release_dev_ucontext(struct c4iw_rdev *rdev,
-       list_for_each_safe(pos, nxt, &uctx->qpids) {
-               entry = list_entry(pos, struct c4iw_qid_list, entry);
-               list_del_init(&entry->entry);
--              if (!(entry->qid & rdev->qpmask))
-+              if (!(entry->qid & rdev->qpmask)) {
-                       c4iw_put_resource(&rdev->resource.qid_fifo, entry->qid,
--                                        &rdev->resource.qid_fifo_lock);
-+                                      &rdev->resource.qid_fifo_lock);
-+                      mutex_lock(&rdev->stats.lock);
-+                      rdev->stats.qid.cur -= rdev->qpmask + 1;
-+                      mutex_unlock(&rdev->stats.lock);
-+              }
-               kfree(entry);
-       }
-
-@@ -332,6 +398,13 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev)
-               goto err1;
-       }
-
-+      rdev->stats.pd.total = T4_MAX_NUM_PD;
-+      rdev->stats.stag.total = rdev->lldi.vr->stag.size;
-+      rdev->stats.pbl.total = rdev->lldi.vr->pbl.size;
-+      rdev->stats.rqt.total = rdev->lldi.vr->rq.size;
-+      rdev->stats.ocqp.total = rdev->lldi.vr->ocq.size;
-+      rdev->stats.qid.total = rdev->lldi.vr->qp.size;
-+
-       err = c4iw_init_resource(rdev, c4iw_num_stags(rdev), T4_MAX_NUM_PD);
-       if (err) {
-               printk(KERN_ERR MOD "error %d initializing resources\n", err);
-@@ -440,6 +513,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
-       idr_init(&devp->qpidr);
-       idr_init(&devp->mmidr);
-       spin_lock_init(&devp->lock);
-+      mutex_init(&devp->rdev.stats.lock);
-
-       if (c4iw_debugfs_root) {
-               devp->debugfs_root = debugfs_create_dir(
-diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-index 1357c5b..a849074 100644
---- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-@@ -103,6 +103,22 @@ enum c4iw_rdev_flags {
-       T4_FATAL_ERROR = (1<<0),
- };
-
-+struct c4iw_stat {
-+      u64 total;
-+      u64 cur;
-+      u64 max;
-+};
-+
-+struct c4iw_stats {
-+      struct mutex lock;
-+      struct c4iw_stat qid;
-+      struct c4iw_stat pd;
-+      struct c4iw_stat stag;
-+      struct c4iw_stat pbl;
-+      struct c4iw_stat rqt;
-+      struct c4iw_stat ocqp;
-+};
-+
- struct c4iw_rdev {
-       struct c4iw_resource resource;
-       unsigned long qpshift;
-@@ -117,6 +133,7 @@ struct c4iw_rdev {
-       struct cxgb4_lld_info lldi;
-       unsigned long oc_mw_pa;
-       void __iomem *oc_mw_kva;
-+      struct c4iw_stats stats;
- };
-
- static inline int c4iw_fatal_error(struct c4iw_rdev *rdev)
-diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
-index 40c8353..2a87379 100644
---- a/drivers/infiniband/hw/cxgb4/mem.c
-+++ b/drivers/infiniband/hw/cxgb4/mem.c
-@@ -135,6 +135,11 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
-                                            &rdev->resource.tpt_fifo_lock);
-               if (!stag_idx)
-                       return -ENOMEM;
-+              mutex_lock(&rdev->stats.lock);
-+              rdev->stats.stag.cur += 32;
-+              if (rdev->stats.stag.cur > rdev->stats.stag.max)
-+                      rdev->stats.stag.max = rdev->stats.stag.cur;
-+              mutex_unlock(&rdev->stats.lock);
-               *stag = (stag_idx << 8) | (atomic_inc_return(&key) & 0xff);
-       }
-       PDBG("%s stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n",
-@@ -165,9 +170,13 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
-                               (rdev->lldi.vr->stag.start >> 5),
-                               sizeof(tpt), &tpt);
-
--      if (reset_tpt_entry)
-+      if (reset_tpt_entry) {
-               c4iw_put_resource(&rdev->resource.tpt_fifo, stag_idx,
-                                 &rdev->resource.tpt_fifo_lock);
-+              mutex_lock(&rdev->stats.lock);
-+              rdev->stats.stag.cur -= 32;
-+              mutex_unlock(&rdev->stats.lock);
-+      }
-       return err;
- }
-
-diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
-index be1c18f..8d58736 100644
---- a/drivers/infiniband/hw/cxgb4/provider.c
-+++ b/drivers/infiniband/hw/cxgb4/provider.c
-@@ -190,6 +190,9 @@ static int c4iw_deallocate_pd(struct ib_pd *pd)
-       PDBG("%s ibpd %p pdid 0x%x\n", __func__, pd, php->pdid);
-       c4iw_put_resource(&rhp->rdev.resource.pdid_fifo, php->pdid,
-                         &rhp->rdev.resource.pdid_fifo_lock);
-+      mutex_lock(&rhp->rdev.stats.lock);
-+      rhp->rdev.stats.pd.cur--;
-+      mutex_unlock(&rhp->rdev.stats.lock);
-       kfree(php);
-       return 0;
- }
-@@ -222,6 +225,11 @@ static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev,
-                       return ERR_PTR(-EFAULT);
-               }
-       }
-+      mutex_lock(&rhp->rdev.stats.lock);
-+      rhp->rdev.stats.pd.cur++;
-+      if (rhp->rdev.stats.pd.cur > rhp->rdev.stats.pd.max)
-+              rhp->rdev.stats.pd.max = rhp->rdev.stats.pd.cur;
-+      mutex_unlock(&rhp->rdev.stats.lock);
-       PDBG("%s pdid 0x%0x ptr 0x%p\n", __func__, pdid, php);
-       return &php->ibpd;
- }
-diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c
-index 407ff39..1b948d1 100644
---- a/drivers/infiniband/hw/cxgb4/resource.c
-+++ b/drivers/infiniband/hw/cxgb4/resource.c
-@@ -185,6 +185,9 @@ u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
-                                       &rdev->resource.qid_fifo_lock);
-               if (!qid)
-                       goto out;
-+              mutex_lock(&rdev->stats.lock);
-+              rdev->stats.qid.cur += rdev->qpmask + 1;
-+              mutex_unlock(&rdev->stats.lock);
-               for (i = qid+1; i & rdev->qpmask; i++) {
-                       entry = kmalloc(sizeof *entry, GFP_KERNEL);
-                       if (!entry)
-@@ -213,6 +216,10 @@ u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
- out:
-       mutex_unlock(&uctx->lock);
-       PDBG("%s qid 0x%x\n", __func__, qid);
-+      mutex_lock(&rdev->stats.lock);
-+      if (rdev->stats.qid.cur > rdev->stats.qid.max)
-+              rdev->stats.qid.max = rdev->stats.qid.cur;
-+      mutex_unlock(&rdev->stats.lock);
-       return qid;
- }
-
-@@ -249,6 +256,9 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
-                                       &rdev->resource.qid_fifo_lock);
-               if (!qid)
-                       goto out;
-+              mutex_lock(&rdev->stats.lock);
-+              rdev->stats.qid.cur += rdev->qpmask + 1;
-+              mutex_unlock(&rdev->stats.lock);
-               for (i = qid+1; i & rdev->qpmask; i++) {
-                       entry = kmalloc(sizeof *entry, GFP_KERNEL);
-                       if (!entry)
-@@ -277,6 +287,10 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
- out:
-       mutex_unlock(&uctx->lock);
-       PDBG("%s qid 0x%x\n", __func__, qid);
-+      mutex_lock(&rdev->stats.lock);
-+      if (rdev->stats.qid.cur > rdev->stats.qid.max)
-+              rdev->stats.qid.max = rdev->stats.qid.cur;
-+      mutex_unlock(&rdev->stats.lock);
-       return qid;
- }
-
-@@ -315,12 +329,22 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size)
-       if (!addr)
-               printk_ratelimited(KERN_WARNING MOD "%s: Out of PBL memory\n",
-                      pci_name(rdev->lldi.pdev));
-+      if (addr) {
-+              mutex_lock(&rdev->stats.lock);
-+              rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT);
-+              if (rdev->stats.pbl.cur > rdev->stats.pbl.max)
-+                      rdev->stats.pbl.max = rdev->stats.pbl.cur;
-+              mutex_unlock(&rdev->stats.lock);
-+      }
-       return (u32)addr;
- }
-
- void c4iw_pblpool_free(struct c4iw_rdev *rdev, u32 addr, int size)
- {
-       PDBG("%s addr 0x%x size %d\n", __func__, addr, size);
-+      mutex_lock(&rdev->stats.lock);
-+      rdev->stats.pbl.cur -= roundup(size, 1 << MIN_PBL_SHIFT);
-+      mutex_unlock(&rdev->stats.lock);
-       gen_pool_free(rdev->pbl_pool, (unsigned long)addr, size);
- }
-
-@@ -377,12 +401,22 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size)
-       if (!addr)
-               printk_ratelimited(KERN_WARNING MOD "%s: Out of RQT memory\n",
-                      pci_name(rdev->lldi.pdev));
-+      if (addr) {
-+              mutex_lock(&rdev->stats.lock);
-+              rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT);
-+              if (rdev->stats.rqt.cur > rdev->stats.rqt.max)
-+                      rdev->stats.rqt.max = rdev->stats.rqt.cur;
-+              mutex_unlock(&rdev->stats.lock);
-+      }
-       return (u32)addr;
- }
-
- void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size)
- {
-       PDBG("%s addr 0x%x size %d\n", __func__, addr, size << 6);
-+      mutex_lock(&rdev->stats.lock);
-+      rdev->stats.rqt.cur -= roundup(size << 6, 1 << MIN_RQT_SHIFT);
-+      mutex_unlock(&rdev->stats.lock);
-       gen_pool_free(rdev->rqt_pool, (unsigned long)addr, size << 6);
- }
-
-@@ -433,12 +467,22 @@ u32 c4iw_ocqp_pool_alloc(struct c4iw_rdev *rdev, int size)
- {
-       unsigned long addr = gen_pool_alloc(rdev->ocqp_pool, size);
-       PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size);
-+      if (addr) {
-+              mutex_lock(&rdev->stats.lock);
-+              rdev->stats.ocqp.cur += roundup(size, 1 << MIN_OCQP_SHIFT);
-+              if (rdev->stats.ocqp.cur > rdev->stats.ocqp.max)
-+                      rdev->stats.ocqp.max = rdev->stats.ocqp.cur;
-+              mutex_unlock(&rdev->stats.lock);
-+      }
-       return (u32)addr;
- }
-
- void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size)
- {
-       PDBG("%s addr 0x%x size %d\n", __func__, addr, size);
-+      mutex_lock(&rdev->stats.lock);
-+      rdev->stats.ocqp.cur -= roundup(size, 1 << MIN_OCQP_SHIFT);
-+      mutex_unlock(&rdev->stats.lock);
-       gen_pool_free(rdev->ocqp_pool, (unsigned long)addr, size);
- }
-
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/05-RDMA-cxgb4-Add-DB-Overflow-Avoidance.patch b/linux-next-cherry-picks/05-RDMA-cxgb4-Add-DB-Overflow-Avoidance.patch
deleted file mode 100644 (file)
index a6fa97c..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-From 2c97478106880a5fb241a473252e61845a69386e Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:28 +0530
-Subject: [PATCH 08/13] RDMA/cxgb4: Add DB Overflow Avoidance
-
-Get FULL/EMPTY/DROP events from LLD.  On FULL event, disable normal
-user mode DB rings.
-
-Add modify_qp semantics to allow user processes to call into the
-kernel to ring doobells without overflowing.
-
-Add DB Full/Empty/Drop stats.
-
-Mark queues when created indicating the doorbell state.
-
-If we're in the middle of db overflow avoidance, then newly created
-queues should start out in this mode.
-
-Bump the C4IW_UVERBS_ABI_VERSION to 2 so the user mode library can
-know if the driver supports the kernel mode db ringing.
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/infiniband/hw/cxgb4/device.c   |   84 +++++++++++++++++++++++++++++--
- drivers/infiniband/hw/cxgb4/iw_cxgb4.h |   37 ++++++++++++--
- drivers/infiniband/hw/cxgb4/qp.c       |   51 +++++++++++++++++++-
- drivers/infiniband/hw/cxgb4/user.h     |    2 +-
- 4 files changed, 162 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
-index 8483111..9062ed9 100644
---- a/drivers/infiniband/hw/cxgb4/device.c
-+++ b/drivers/infiniband/hw/cxgb4/device.c
-@@ -44,6 +44,12 @@ MODULE_DESCRIPTION("Chelsio T4 RDMA Driver");
- MODULE_LICENSE("Dual BSD/GPL");
- MODULE_VERSION(DRV_VERSION);
-
-+struct uld_ctx {
-+      struct list_head entry;
-+      struct cxgb4_lld_info lldi;
-+      struct c4iw_dev *dev;
-+};
-+
- static LIST_HEAD(uld_ctx_list);
- static DEFINE_MUTEX(dev_mutex);
-
-@@ -263,6 +269,9 @@ static int stats_show(struct seq_file *seq, void *v)
-       seq_printf(seq, "  OCQPMEM: %10llu %10llu %10llu\n",
-                       dev->rdev.stats.ocqp.total, dev->rdev.stats.ocqp.cur,
-                       dev->rdev.stats.ocqp.max);
-+      seq_printf(seq, "  DB FULL: %10llu\n", dev->rdev.stats.db_full);
-+      seq_printf(seq, " DB EMPTY: %10llu\n", dev->rdev.stats.db_empty);
-+      seq_printf(seq, "  DB DROP: %10llu\n", dev->rdev.stats.db_drop);
-       return 0;
- }
-
-@@ -283,6 +292,9 @@ static ssize_t stats_clear(struct file *file, const char __user *buf,
-       dev->rdev.stats.pbl.max = 0;
-       dev->rdev.stats.rqt.max = 0;
-       dev->rdev.stats.ocqp.max = 0;
-+      dev->rdev.stats.db_full = 0;
-+      dev->rdev.stats.db_empty = 0;
-+      dev->rdev.stats.db_drop = 0;
-       mutex_unlock(&dev->rdev.stats.lock);
-       return count;
- }
-@@ -443,12 +455,6 @@ static void c4iw_rdev_close(struct c4iw_rdev *rdev)
-       c4iw_destroy_resource(&rdev->resource);
- }
-
--struct uld_ctx {
--      struct list_head entry;
--      struct cxgb4_lld_info lldi;
--      struct c4iw_dev *dev;
--};
--
- static void c4iw_dealloc(struct uld_ctx *ctx)
- {
-       c4iw_rdev_close(&ctx->dev->rdev);
-@@ -514,6 +520,7 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
-       idr_init(&devp->mmidr);
-       spin_lock_init(&devp->lock);
-       mutex_init(&devp->rdev.stats.lock);
-+      mutex_init(&devp->db_mutex);
-
-       if (c4iw_debugfs_root) {
-               devp->debugfs_root = debugfs_create_dir(
-@@ -659,11 +666,76 @@ static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state)
-       return 0;
- }
-
-+static int disable_qp_db(int id, void *p, void *data)
-+{
-+      struct c4iw_qp *qp = p;
-+
-+      t4_disable_wq_db(&qp->wq);
-+      return 0;
-+}
-+
-+static void stop_queues(struct uld_ctx *ctx)
-+{
-+      spin_lock_irq(&ctx->dev->lock);
-+      ctx->dev->db_state = FLOW_CONTROL;
-+      idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL);
-+      spin_unlock_irq(&ctx->dev->lock);
-+}
-+
-+static int enable_qp_db(int id, void *p, void *data)
-+{
-+      struct c4iw_qp *qp = p;
-+
-+      t4_enable_wq_db(&qp->wq);
-+      return 0;
-+}
-+
-+static void resume_queues(struct uld_ctx *ctx)
-+{
-+      spin_lock_irq(&ctx->dev->lock);
-+      ctx->dev->db_state = NORMAL;
-+      idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL);
-+      spin_unlock_irq(&ctx->dev->lock);
-+}
-+
-+static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...)
-+{
-+      struct uld_ctx *ctx = handle;
-+
-+      switch (control) {
-+      case CXGB4_CONTROL_DB_FULL:
-+              stop_queues(ctx);
-+              mutex_lock(&ctx->dev->rdev.stats.lock);
-+              ctx->dev->rdev.stats.db_full++;
-+              mutex_unlock(&ctx->dev->rdev.stats.lock);
-+              break;
-+      case CXGB4_CONTROL_DB_EMPTY:
-+              resume_queues(ctx);
-+              mutex_lock(&ctx->dev->rdev.stats.lock);
-+              ctx->dev->rdev.stats.db_empty++;
-+              mutex_unlock(&ctx->dev->rdev.stats.lock);
-+              break;
-+      case CXGB4_CONTROL_DB_DROP:
-+              printk(KERN_WARNING MOD "%s: Fatal DB DROP\n",
-+                     pci_name(ctx->lldi.pdev));
-+              mutex_lock(&ctx->dev->rdev.stats.lock);
-+              ctx->dev->rdev.stats.db_drop++;
-+              mutex_unlock(&ctx->dev->rdev.stats.lock);
-+              break;
-+      default:
-+              printk(KERN_WARNING MOD "%s: unknown control cmd %u\n",
-+                     pci_name(ctx->lldi.pdev), control);
-+              break;
-+      }
-+      return 0;
-+}
-+
- static struct cxgb4_uld_info c4iw_uld_info = {
-       .name = DRV_NAME,
-       .add = c4iw_uld_add,
-       .rx_handler = c4iw_uld_rx_handler,
-       .state_change = c4iw_uld_state_change,
-+      .control = c4iw_uld_control,
- };
-
- static int __init c4iw_init_module(void)
-diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-index a849074..a11ed5c 100644
---- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-@@ -117,6 +117,9 @@ struct c4iw_stats {
-       struct c4iw_stat pbl;
-       struct c4iw_stat rqt;
-       struct c4iw_stat ocqp;
-+      u64  db_full;
-+      u64  db_empty;
-+      u64  db_drop;
- };
-
- struct c4iw_rdev {
-@@ -192,6 +195,12 @@ static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev,
-       return wr_waitp->ret;
- }
-
-+enum db_state {
-+      NORMAL = 0,
-+      FLOW_CONTROL = 1,
-+      RECOVERY = 2
-+};
-+
- struct c4iw_dev {
-       struct ib_device ibdev;
-       struct c4iw_rdev rdev;
-@@ -200,7 +209,9 @@ struct c4iw_dev {
-       struct idr qpidr;
-       struct idr mmidr;
-       spinlock_t lock;
-+      struct mutex db_mutex;
-       struct dentry *debugfs_root;
-+      enum db_state db_state;
- };
-
- static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
-@@ -228,8 +239,8 @@ static inline struct c4iw_mr *get_mhp(struct c4iw_dev *rhp, u32 mmid)
-       return idr_find(&rhp->mmidr, mmid);
- }
-
--static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
--                              void *handle, u32 id)
-+static inline int _insert_handle(struct c4iw_dev *rhp, struct idr *idr,
-+                               void *handle, u32 id, int lock)
- {
-       int ret;
-       int newid;
-@@ -237,15 +248,29 @@ static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
-       do {
-               if (!idr_pre_get(idr, GFP_KERNEL))
-                       return -ENOMEM;
--              spin_lock_irq(&rhp->lock);
-+              if (lock)
-+                      spin_lock_irq(&rhp->lock);
-               ret = idr_get_new_above(idr, handle, id, &newid);
-               BUG_ON(newid != id);
--              spin_unlock_irq(&rhp->lock);
-+              if (lock)
-+                      spin_unlock_irq(&rhp->lock);
-       } while (ret == -EAGAIN);
-
-       return ret;
- }
-
-+static inline int insert_handle(struct c4iw_dev *rhp, struct idr *idr,
-+                              void *handle, u32 id)
-+{
-+      return _insert_handle(rhp, idr, handle, id, 1);
-+}
-+
-+static inline int insert_handle_nolock(struct c4iw_dev *rhp, struct idr *idr,
-+                                     void *handle, u32 id)
-+{
-+      return _insert_handle(rhp, idr, handle, id, 0);
-+}
-+
- static inline void remove_handle(struct c4iw_dev *rhp, struct idr *idr, u32 id)
- {
-       spin_lock_irq(&rhp->lock);
-@@ -370,6 +395,8 @@ struct c4iw_qp_attributes {
-       struct c4iw_ep *llp_stream_handle;
-       u8 layer_etype;
-       u8 ecode;
-+      u16 sq_db_inc;
-+      u16 rq_db_inc;
- };
-
- struct c4iw_qp {
-@@ -444,6 +471,8 @@ static inline void insert_mmap(struct c4iw_ucontext *ucontext,
-
- enum c4iw_qp_attr_mask {
-       C4IW_QP_ATTR_NEXT_STATE = 1 << 0,
-+      C4IW_QP_ATTR_SQ_DB = 1<<1,
-+      C4IW_QP_ATTR_RQ_DB = 1<<2,
-       C4IW_QP_ATTR_ENABLE_RDMA_READ = 1 << 7,
-       C4IW_QP_ATTR_ENABLE_RDMA_WRITE = 1 << 8,
-       C4IW_QP_ATTR_ENABLE_RDMA_BIND = 1 << 9,
-diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
-index 5f940ae..beec667 100644
---- a/drivers/infiniband/hw/cxgb4/qp.c
-+++ b/drivers/infiniband/hw/cxgb4/qp.c
-@@ -34,6 +34,10 @@
-
- #include "iw_cxgb4.h"
-
-+static int db_delay_usecs = 1;
-+module_param(db_delay_usecs, int, 0644);
-+MODULE_PARM_DESC(db_delay_usecs, "Usecs to delay awaiting db fifo to drain");
-+
- static int ocqp_support = 1;
- module_param(ocqp_support, int, 0644);
- MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)");
-@@ -1128,6 +1132,29 @@ out:
-       return ret;
- }
-
-+/*
-+ * Called by the library when the qp has user dbs disabled due to
-+ * a DB_FULL condition.  This function will single-thread all user
-+ * DB rings to avoid overflowing the hw db-fifo.
-+ */
-+static int ring_kernel_db(struct c4iw_qp *qhp, u32 qid, u16 inc)
-+{
-+      int delay = db_delay_usecs;
-+
-+      mutex_lock(&qhp->rhp->db_mutex);
-+      do {
-+              if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) < 768) {
-+                      writel(V_QID(qid) | V_PIDX(inc), qhp->wq.db);
-+                      break;
-+              }
-+              set_current_state(TASK_UNINTERRUPTIBLE);
-+              schedule_timeout(usecs_to_jiffies(delay));
-+              delay = min(delay << 1, 200000);
-+      } while (1);
-+      mutex_unlock(&qhp->rhp->db_mutex);
-+      return 0;
-+}
-+
- int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
-                  enum c4iw_qp_attr_mask mask,
-                  struct c4iw_qp_attributes *attrs,
-@@ -1176,6 +1203,15 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
-               qhp->attr = newattr;
-       }
-
-+      if (mask & C4IW_QP_ATTR_SQ_DB) {
-+              ret = ring_kernel_db(qhp, qhp->wq.sq.qid, attrs->sq_db_inc);
-+              goto out;
-+      }
-+      if (mask & C4IW_QP_ATTR_RQ_DB) {
-+              ret = ring_kernel_db(qhp, qhp->wq.rq.qid, attrs->rq_db_inc);
-+              goto out;
-+      }
-+
-       if (!(mask & C4IW_QP_ATTR_NEXT_STATE))
-               goto out;
-       if (qhp->attr.state == attrs->next_state)
-@@ -1469,7 +1505,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
-       init_waitqueue_head(&qhp->wait);
-       atomic_set(&qhp->refcnt, 1);
-
--      ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
-+      spin_lock_irq(&rhp->lock);
-+      if (rhp->db_state != NORMAL)
-+              t4_disable_wq_db(&qhp->wq);
-+      ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
-+      spin_unlock_irq(&rhp->lock);
-       if (ret)
-               goto err2;
-
-@@ -1613,6 +1653,15 @@ int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
-                        C4IW_QP_ATTR_ENABLE_RDMA_WRITE |
-                        C4IW_QP_ATTR_ENABLE_RDMA_BIND) : 0;
-
-+      /*
-+       * Use SQ_PSN and RQ_PSN to pass in IDX_INC values for
-+       * ringing the queue db when we're in DB_FULL mode.
-+       */
-+      attrs.sq_db_inc = attr->sq_psn;
-+      attrs.rq_db_inc = attr->rq_psn;
-+      mask |= (attr_mask & IB_QP_SQ_PSN) ? C4IW_QP_ATTR_SQ_DB : 0;
-+      mask |= (attr_mask & IB_QP_RQ_PSN) ? C4IW_QP_ATTR_RQ_DB : 0;
-+
-       return c4iw_modify_qp(rhp, qhp, mask, &attrs, 0);
- }
-
-diff --git a/drivers/infiniband/hw/cxgb4/user.h b/drivers/infiniband/hw/cxgb4/user.h
-index e6669d5..32b754c 100644
---- a/drivers/infiniband/hw/cxgb4/user.h
-+++ b/drivers/infiniband/hw/cxgb4/user.h
-@@ -32,7 +32,7 @@
- #ifndef __C4IW_USER_H__
- #define __C4IW_USER_H__
-
--#define C4IW_UVERBS_ABI_VERSION       1
-+#define C4IW_UVERBS_ABI_VERSION       2
-
- /*
-  * Make sure that all structs defined in this file remain laid out so
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/06-RDMA-cxgb4-Disable-interrupts-in-c4iw_ev_dispatch.patch b/linux-next-cherry-picks/06-RDMA-cxgb4-Disable-interrupts-in-c4iw_ev_dispatch.patch
deleted file mode 100644 (file)
index d591d6d..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-From 4984037bef54253d4d010d3e57f175ab694bee26 Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:29 +0530
-Subject: [PATCH 09/13] RDMA/cxgb4: Disable interrupts in c4iw_ev_dispatch()
-
-Use GFP_ATOMIC in _insert_handle() if ints are disabled.
-
-Don't panic if we get an abort with no endpoint found.  Just log a
-warning.
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/infiniband/hw/cxgb4/cm.c       |    5 ++++-
- drivers/infiniband/hw/cxgb4/ev.c       |    8 ++++----
- drivers/infiniband/hw/cxgb4/iw_cxgb4.h |    2 +-
- 3 files changed, 9 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
-index 4c7c62f..6ce401a 100644
---- a/drivers/infiniband/hw/cxgb4/cm.c
-+++ b/drivers/infiniband/hw/cxgb4/cm.c
-@@ -1362,7 +1362,10 @@ static int abort_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
-
-       ep = lookup_tid(t, tid);
-       PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
--      BUG_ON(!ep);
-+      if (!ep) {
-+              printk(KERN_WARNING MOD "Abort rpl to freed endpoint\n");
-+              return 0;
-+      }
-       mutex_lock(&ep->com.mutex);
-       switch (ep->com.state) {
-       case ABORTING:
-diff --git a/drivers/infiniband/hw/cxgb4/ev.c b/drivers/infiniband/hw/cxgb4/ev.c
-index 397cb36..cf2f6b4 100644
---- a/drivers/infiniband/hw/cxgb4/ev.c
-+++ b/drivers/infiniband/hw/cxgb4/ev.c
-@@ -84,7 +84,7 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe)
-       struct c4iw_qp *qhp;
-       u32 cqid;
-
--      spin_lock(&dev->lock);
-+      spin_lock_irq(&dev->lock);
-       qhp = get_qhp(dev, CQE_QPID(err_cqe));
-       if (!qhp) {
-               printk(KERN_ERR MOD "BAD AE qpid 0x%x opcode %d "
-@@ -93,7 +93,7 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe)
-                      CQE_OPCODE(err_cqe), CQE_STATUS(err_cqe),
-                      CQE_TYPE(err_cqe), CQE_WRID_HI(err_cqe),
-                      CQE_WRID_LOW(err_cqe));
--              spin_unlock(&dev->lock);
-+              spin_unlock_irq(&dev->lock);
-               goto out;
-       }
-
-@@ -109,13 +109,13 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe)
-                      CQE_OPCODE(err_cqe), CQE_STATUS(err_cqe),
-                      CQE_TYPE(err_cqe), CQE_WRID_HI(err_cqe),
-                      CQE_WRID_LOW(err_cqe));
--              spin_unlock(&dev->lock);
-+              spin_unlock_irq(&dev->lock);
-               goto out;
-       }
-
-       c4iw_qp_add_ref(&qhp->ibqp);
-       atomic_inc(&chp->refcnt);
--      spin_unlock(&dev->lock);
-+      spin_unlock_irq(&dev->lock);
-
-       /* Bad incoming write */
-       if (RQ_TYPE(err_cqe) &&
-diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-index a11ed5c..e8b88a0 100644
---- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-@@ -246,7 +246,7 @@ static inline int _insert_handle(struct c4iw_dev *rhp, struct idr *idr,
-       int newid;
-
-       do {
--              if (!idr_pre_get(idr, GFP_KERNEL))
-+              if (!idr_pre_get(idr, lock ? GFP_KERNEL : GFP_ATOMIC))
-                       return -ENOMEM;
-               if (lock)
-                       spin_lock_irq(&rhp->lock);
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/07-RDMA-cxgb4-DB-Drop-Recovery-for-RDMA-and-LLD-queues.patch b/linux-next-cherry-picks/07-RDMA-cxgb4-DB-Drop-Recovery-for-RDMA-and-LLD-queues.patch
deleted file mode 100644 (file)
index fed815b..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-From 422eea0a8cf658bc9564726d74e8384b89a8f4fa Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:30 +0530
-Subject: [PATCH 10/13] RDMA/cxgb4: DB Drop Recovery for RDMA and LLD queues
-
-Add module option db_fc_threshold which is the count of active QPs
-that trigger automatic db flow control mode.  Automatically transition
-to/from flow control mode when the active qp count crosses
-db_fc_theshold.
-
-Add more db debugfs stats
-
-On DB DROP event from the LLD, recover all the iwarp queues.
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/infiniband/hw/cxgb4/device.c   |  176 ++++++++++++++++++++++++++++++-
- drivers/infiniband/hw/cxgb4/iw_cxgb4.h |   24 ++++-
- drivers/infiniband/hw/cxgb4/qp.c       |   47 ++++++++-
- drivers/infiniband/hw/cxgb4/t4.h       |   24 +++++
- 4 files changed, 259 insertions(+), 12 deletions(-)
-
-diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
-index 9062ed9..bdb398f 100644
---- a/drivers/infiniband/hw/cxgb4/device.c
-+++ b/drivers/infiniband/hw/cxgb4/device.c
-@@ -246,6 +246,8 @@ static const struct file_operations stag_debugfs_fops = {
-       .llseek  = default_llseek,
- };
-
-+static char *db_state_str[] = {"NORMAL", "FLOW_CONTROL", "RECOVERY"};
-+
- static int stats_show(struct seq_file *seq, void *v)
- {
-       struct c4iw_dev *dev = seq->private;
-@@ -272,6 +274,9 @@ static int stats_show(struct seq_file *seq, void *v)
-       seq_printf(seq, "  DB FULL: %10llu\n", dev->rdev.stats.db_full);
-       seq_printf(seq, " DB EMPTY: %10llu\n", dev->rdev.stats.db_empty);
-       seq_printf(seq, "  DB DROP: %10llu\n", dev->rdev.stats.db_drop);
-+      seq_printf(seq, " DB State: %s Transitions %llu\n",
-+                 db_state_str[dev->db_state],
-+                 dev->rdev.stats.db_state_transitions);
-       return 0;
- }
-
-@@ -295,6 +300,7 @@ static ssize_t stats_clear(struct file *file, const char __user *buf,
-       dev->rdev.stats.db_full = 0;
-       dev->rdev.stats.db_empty = 0;
-       dev->rdev.stats.db_drop = 0;
-+      dev->rdev.stats.db_state_transitions = 0;
-       mutex_unlock(&dev->rdev.stats.lock);
-       return count;
- }
-@@ -677,8 +683,11 @@ static int disable_qp_db(int id, void *p, void *data)
- static void stop_queues(struct uld_ctx *ctx)
- {
-       spin_lock_irq(&ctx->dev->lock);
--      ctx->dev->db_state = FLOW_CONTROL;
--      idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL);
-+      if (ctx->dev->db_state == NORMAL) {
-+              ctx->dev->rdev.stats.db_state_transitions++;
-+              ctx->dev->db_state = FLOW_CONTROL;
-+              idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL);
-+      }
-       spin_unlock_irq(&ctx->dev->lock);
- }
-
-@@ -693,9 +702,165 @@ static int enable_qp_db(int id, void *p, void *data)
- static void resume_queues(struct uld_ctx *ctx)
- {
-       spin_lock_irq(&ctx->dev->lock);
--      ctx->dev->db_state = NORMAL;
--      idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL);
-+      if (ctx->dev->qpcnt <= db_fc_threshold &&
-+          ctx->dev->db_state == FLOW_CONTROL) {
-+              ctx->dev->db_state = NORMAL;
-+              ctx->dev->rdev.stats.db_state_transitions++;
-+              idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL);
-+      }
-+      spin_unlock_irq(&ctx->dev->lock);
-+}
-+
-+struct qp_list {
-+      unsigned idx;
-+      struct c4iw_qp **qps;
-+};
-+
-+static int add_and_ref_qp(int id, void *p, void *data)
-+{
-+      struct qp_list *qp_listp = data;
-+      struct c4iw_qp *qp = p;
-+
-+      c4iw_qp_add_ref(&qp->ibqp);
-+      qp_listp->qps[qp_listp->idx++] = qp;
-+      return 0;
-+}
-+
-+static int count_qps(int id, void *p, void *data)
-+{
-+      unsigned *countp = data;
-+      (*countp)++;
-+      return 0;
-+}
-+
-+static void deref_qps(struct qp_list qp_list)
-+{
-+      int idx;
-+
-+      for (idx = 0; idx < qp_list.idx; idx++)
-+              c4iw_qp_rem_ref(&qp_list.qps[idx]->ibqp);
-+}
-+
-+static void recover_lost_dbs(struct uld_ctx *ctx, struct qp_list *qp_list)
-+{
-+      int idx;
-+      int ret;
-+
-+      for (idx = 0; idx < qp_list->idx; idx++) {
-+              struct c4iw_qp *qp = qp_list->qps[idx];
-+
-+              ret = cxgb4_sync_txq_pidx(qp->rhp->rdev.lldi.ports[0],
-+                                        qp->wq.sq.qid,
-+                                        t4_sq_host_wq_pidx(&qp->wq),
-+                                        t4_sq_wq_size(&qp->wq));
-+              if (ret) {
-+                      printk(KERN_ERR MOD "%s: Fatal error - "
-+                             "DB overflow recovery failed - "
-+                             "error syncing SQ qid %u\n",
-+                             pci_name(ctx->lldi.pdev), qp->wq.sq.qid);
-+                      return;
-+              }
-+
-+              ret = cxgb4_sync_txq_pidx(qp->rhp->rdev.lldi.ports[0],
-+                                        qp->wq.rq.qid,
-+                                        t4_rq_host_wq_pidx(&qp->wq),
-+                                        t4_rq_wq_size(&qp->wq));
-+
-+              if (ret) {
-+                      printk(KERN_ERR MOD "%s: Fatal error - "
-+                             "DB overflow recovery failed - "
-+                             "error syncing RQ qid %u\n",
-+                             pci_name(ctx->lldi.pdev), qp->wq.rq.qid);
-+                      return;
-+              }
-+
-+              /* Wait for the dbfifo to drain */
-+              while (cxgb4_dbfifo_count(qp->rhp->rdev.lldi.ports[0], 1) > 0) {
-+                      set_current_state(TASK_UNINTERRUPTIBLE);
-+                      schedule_timeout(usecs_to_jiffies(10));
-+              }
-+      }
-+}
-+
-+static void recover_queues(struct uld_ctx *ctx)
-+{
-+      int count = 0;
-+      struct qp_list qp_list;
-+      int ret;
-+
-+      /* lock out kernel db ringers */
-+      mutex_lock(&ctx->dev->db_mutex);
-+
-+      /* put all queues in to recovery mode */
-+      spin_lock_irq(&ctx->dev->lock);
-+      ctx->dev->db_state = RECOVERY;
-+      ctx->dev->rdev.stats.db_state_transitions++;
-+      idr_for_each(&ctx->dev->qpidr, disable_qp_db, NULL);
-+      spin_unlock_irq(&ctx->dev->lock);
-+
-+      /* slow everybody down */
-+      set_current_state(TASK_UNINTERRUPTIBLE);
-+      schedule_timeout(usecs_to_jiffies(1000));
-+
-+      /* Wait for the dbfifo to completely drain. */
-+      while (cxgb4_dbfifo_count(ctx->dev->rdev.lldi.ports[0], 1) > 0) {
-+              set_current_state(TASK_UNINTERRUPTIBLE);
-+              schedule_timeout(usecs_to_jiffies(10));
-+      }
-+
-+      /* flush the SGE contexts */
-+      ret = cxgb4_flush_eq_cache(ctx->dev->rdev.lldi.ports[0]);
-+      if (ret) {
-+              printk(KERN_ERR MOD "%s: Fatal error - DB overflow recovery failed\n",
-+                     pci_name(ctx->lldi.pdev));
-+              goto out;
-+      }
-+
-+      /* Count active queues so we can build a list of queues to recover */
-+      spin_lock_irq(&ctx->dev->lock);
-+      idr_for_each(&ctx->dev->qpidr, count_qps, &count);
-+
-+      qp_list.qps = kzalloc(count * sizeof *qp_list.qps, GFP_ATOMIC);
-+      if (!qp_list.qps) {
-+              printk(KERN_ERR MOD "%s: Fatal error - DB overflow recovery failed\n",
-+                     pci_name(ctx->lldi.pdev));
-+              spin_unlock_irq(&ctx->dev->lock);
-+              goto out;
-+      }
-+      qp_list.idx = 0;
-+
-+      /* add and ref each qp so it doesn't get freed */
-+      idr_for_each(&ctx->dev->qpidr, add_and_ref_qp, &qp_list);
-+
-       spin_unlock_irq(&ctx->dev->lock);
-+
-+      /* now traverse the list in a safe context to recover the db state*/
-+      recover_lost_dbs(ctx, &qp_list);
-+
-+      /* we're almost done!  deref the qps and clean up */
-+      deref_qps(qp_list);
-+      kfree(qp_list.qps);
-+
-+      /* Wait for the dbfifo to completely drain again */
-+      while (cxgb4_dbfifo_count(ctx->dev->rdev.lldi.ports[0], 1) > 0) {
-+              set_current_state(TASK_UNINTERRUPTIBLE);
-+              schedule_timeout(usecs_to_jiffies(10));
-+      }
-+
-+      /* resume the queues */
-+      spin_lock_irq(&ctx->dev->lock);
-+      if (ctx->dev->qpcnt > db_fc_threshold)
-+              ctx->dev->db_state = FLOW_CONTROL;
-+      else {
-+              ctx->dev->db_state = NORMAL;
-+              idr_for_each(&ctx->dev->qpidr, enable_qp_db, NULL);
-+      }
-+      ctx->dev->rdev.stats.db_state_transitions++;
-+      spin_unlock_irq(&ctx->dev->lock);
-+
-+out:
-+      /* start up kernel db ringers again */
-+      mutex_unlock(&ctx->dev->db_mutex);
- }
-
- static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...)
-@@ -716,8 +881,7 @@ static int c4iw_uld_control(void *handle, enum cxgb4_control control, ...)
-               mutex_unlock(&ctx->dev->rdev.stats.lock);
-               break;
-       case CXGB4_CONTROL_DB_DROP:
--              printk(KERN_WARNING MOD "%s: Fatal DB DROP\n",
--                     pci_name(ctx->lldi.pdev));
-+              recover_queues(ctx);
-               mutex_lock(&ctx->dev->rdev.stats.lock);
-               ctx->dev->rdev.stats.db_drop++;
-               mutex_unlock(&ctx->dev->rdev.stats.lock);
-diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-index e8b88a0..6818659 100644
---- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-@@ -120,6 +120,7 @@ struct c4iw_stats {
-       u64  db_full;
-       u64  db_empty;
-       u64  db_drop;
-+      u64  db_state_transitions;
- };
-
- struct c4iw_rdev {
-@@ -212,6 +213,7 @@ struct c4iw_dev {
-       struct mutex db_mutex;
-       struct dentry *debugfs_root;
-       enum db_state db_state;
-+      int qpcnt;
- };
-
- static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
-@@ -271,11 +273,25 @@ static inline int insert_handle_nolock(struct c4iw_dev *rhp, struct idr *idr,
-       return _insert_handle(rhp, idr, handle, id, 0);
- }
-
--static inline void remove_handle(struct c4iw_dev *rhp, struct idr *idr, u32 id)
-+static inline void _remove_handle(struct c4iw_dev *rhp, struct idr *idr,
-+                                 u32 id, int lock)
- {
--      spin_lock_irq(&rhp->lock);
-+      if (lock)
-+              spin_lock_irq(&rhp->lock);
-       idr_remove(idr, id);
--      spin_unlock_irq(&rhp->lock);
-+      if (lock)
-+              spin_unlock_irq(&rhp->lock);
-+}
-+
-+static inline void remove_handle(struct c4iw_dev *rhp, struct idr *idr, u32 id)
-+{
-+      _remove_handle(rhp, idr, id, 1);
-+}
-+
-+static inline void remove_handle_nolock(struct c4iw_dev *rhp,
-+                                       struct idr *idr, u32 id)
-+{
-+      _remove_handle(rhp, idr, id, 0);
- }
-
- struct c4iw_pd {
-@@ -843,5 +859,7 @@ void c4iw_ev_dispatch(struct c4iw_dev *dev, struct t4_cqe *err_cqe);
- extern struct cxgb4_client t4c_client;
- extern c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS];
- extern int c4iw_max_read_depth;
-+extern int db_fc_threshold;
-+
-
- #endif
-diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
-index beec667..ba1343e 100644
---- a/drivers/infiniband/hw/cxgb4/qp.c
-+++ b/drivers/infiniband/hw/cxgb4/qp.c
-@@ -42,6 +42,11 @@ static int ocqp_support = 1;
- module_param(ocqp_support, int, 0644);
- MODULE_PARM_DESC(ocqp_support, "Support on-chip SQs (default=1)");
-
-+int db_fc_threshold = 2000;
-+module_param(db_fc_threshold, int, 0644);
-+MODULE_PARM_DESC(db_fc_threshold, "QP count/threshold that triggers automatic "
-+               "db flow control mode (default = 2000)");
-+
- static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state)
- {
-       unsigned long flag;
-@@ -1143,13 +1148,19 @@ static int ring_kernel_db(struct c4iw_qp *qhp, u32 qid, u16 inc)
-
-       mutex_lock(&qhp->rhp->db_mutex);
-       do {
--              if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) < 768) {
-+
-+              /*
-+               * The interrupt threshold is dbfifo_int_thresh << 6. So
-+               * make sure we don't cross that and generate an interrupt.
-+               */
-+              if (cxgb4_dbfifo_count(qhp->rhp->rdev.lldi.ports[0], 1) <
-+                  (qhp->rhp->rdev.lldi.dbfifo_int_thresh << 5)) {
-                       writel(V_QID(qid) | V_PIDX(inc), qhp->wq.db);
-                       break;
-               }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(usecs_to_jiffies(delay));
--              delay = min(delay << 1, 200000);
-+              delay = min(delay << 1, 2000);
-       } while (1);
-       mutex_unlock(&qhp->rhp->db_mutex);
-       return 0;
-@@ -1388,6 +1399,14 @@ out:
-       return ret;
- }
-
-+static int enable_qp_db(int id, void *p, void *data)
-+{
-+      struct c4iw_qp *qp = p;
-+
-+      t4_enable_wq_db(&qp->wq);
-+      return 0;
-+}
-+
- int c4iw_destroy_qp(struct ib_qp *ib_qp)
- {
-       struct c4iw_dev *rhp;
-@@ -1405,7 +1424,16 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
-               c4iw_modify_qp(rhp, qhp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 0);
-       wait_event(qhp->wait, !qhp->ep);
-
--      remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid);
-+      spin_lock_irq(&rhp->lock);
-+      remove_handle_nolock(rhp, &rhp->qpidr, qhp->wq.sq.qid);
-+      rhp->qpcnt--;
-+      BUG_ON(rhp->qpcnt < 0);
-+      if (rhp->qpcnt <= db_fc_threshold && rhp->db_state == FLOW_CONTROL) {
-+              rhp->rdev.stats.db_state_transitions++;
-+              rhp->db_state = NORMAL;
-+              idr_for_each(&rhp->qpidr, enable_qp_db, NULL);
-+      }
-+      spin_unlock_irq(&rhp->lock);
-       atomic_dec(&qhp->refcnt);
-       wait_event(qhp->wait, !atomic_read(&qhp->refcnt));
-
-@@ -1419,6 +1447,14 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
-       return 0;
- }
-
-+static int disable_qp_db(int id, void *p, void *data)
-+{
-+      struct c4iw_qp *qp = p;
-+
-+      t4_disable_wq_db(&qp->wq);
-+      return 0;
-+}
-+
- struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
-                            struct ib_udata *udata)
- {
-@@ -1508,6 +1544,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
-       spin_lock_irq(&rhp->lock);
-       if (rhp->db_state != NORMAL)
-               t4_disable_wq_db(&qhp->wq);
-+      if (++rhp->qpcnt > db_fc_threshold && rhp->db_state == NORMAL) {
-+              rhp->rdev.stats.db_state_transitions++;
-+              rhp->db_state = FLOW_CONTROL;
-+              idr_for_each(&rhp->qpidr, disable_qp_db, NULL);
-+      }
-       ret = insert_handle_nolock(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
-       spin_unlock_irq(&rhp->lock);
-       if (ret)
-diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h
-index c0221ee..16f26ab 100644
---- a/drivers/infiniband/hw/cxgb4/t4.h
-+++ b/drivers/infiniband/hw/cxgb4/t4.h
-@@ -62,6 +62,10 @@ struct t4_status_page {
-       __be16 pidx;
-       u8 qp_err;      /* flit 1 - sw owns */
-       u8 db_off;
-+      u8 pad;
-+      u16 host_wq_pidx;
-+      u16 host_cidx;
-+      u16 host_pidx;
- };
-
- #define T4_EQ_ENTRY_SIZE 64
-@@ -375,6 +379,16 @@ static inline void t4_rq_consume(struct t4_wq *wq)
-               wq->rq.cidx = 0;
- }
-
-+static inline u16 t4_rq_host_wq_pidx(struct t4_wq *wq)
-+{
-+      return wq->rq.queue[wq->rq.size].status.host_wq_pidx;
-+}
-+
-+static inline u16 t4_rq_wq_size(struct t4_wq *wq)
-+{
-+              return wq->rq.size * T4_RQ_NUM_SLOTS;
-+}
-+
- static inline int t4_sq_onchip(struct t4_sq *sq)
- {
-       return sq->flags & T4_SQ_ONCHIP;
-@@ -412,6 +426,16 @@ static inline void t4_sq_consume(struct t4_wq *wq)
-               wq->sq.cidx = 0;
- }
-
-+static inline u16 t4_sq_host_wq_pidx(struct t4_wq *wq)
-+{
-+      return wq->sq.queue[wq->sq.size].status.host_wq_pidx;
-+}
-+
-+static inline u16 t4_sq_wq_size(struct t4_wq *wq)
-+{
-+              return wq->sq.size * T4_SQ_NUM_SLOTS;
-+}
-+
- static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc)
- {
-       wmb();
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/08-RDMA-cxgb4-Use-vmalloc-for-debugfs-QP-dump.patch b/linux-next-cherry-picks/08-RDMA-cxgb4-Use-vmalloc-for-debugfs-QP-dump.patch
deleted file mode 100644 (file)
index 44440a8..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-From d716a2a014ad199362a59004b5ab932030a213ff Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:31 +0530
-Subject: [PATCH 11/13] RDMA/cxgb4: Use vmalloc() for debugfs QP dump
-
-This allows dumping thousands of QPs.  Log active open failures of
-interest.
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/infiniband/hw/cxgb4/cm.c     |   18 ++++++++++++++++++
- drivers/infiniband/hw/cxgb4/device.c |    4 ++--
- 2 files changed, 20 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
-index 6ce401a..55ab284 100644
---- a/drivers/infiniband/hw/cxgb4/cm.c
-+++ b/drivers/infiniband/hw/cxgb4/cm.c
-@@ -1413,6 +1413,24 @@ static int act_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
-               return 0;
-       }
-
-+      /*
-+       * Log interesting failures.
-+       */
-+      switch (status) {
-+      case CPL_ERR_CONN_RESET:
-+      case CPL_ERR_CONN_TIMEDOUT:
-+              break;
-+      default:
-+              printk(KERN_INFO MOD "Active open failure - "
-+                     "atid %u status %u errno %d %pI4:%u->%pI4:%u\n",
-+                     atid, status, status2errno(status),
-+                     &ep->com.local_addr.sin_addr.s_addr,
-+                     ntohs(ep->com.local_addr.sin_port),
-+                     &ep->com.remote_addr.sin_addr.s_addr,
-+                     ntohs(ep->com.remote_addr.sin_port));
-+              break;
-+      }
-+
-       connect_reply_upcall(ep, status2errno(status));
-       state_set(&ep->com, DEAD);
-
-diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
-index bdb398f..8545629 100644
---- a/drivers/infiniband/hw/cxgb4/device.c
-+++ b/drivers/infiniband/hw/cxgb4/device.c
-@@ -121,7 +121,7 @@ static int qp_release(struct inode *inode, struct file *file)
-               printk(KERN_INFO "%s null qpd?\n", __func__);
-               return 0;
-       }
--      kfree(qpd->buf);
-+      vfree(qpd->buf);
-       kfree(qpd);
-       return 0;
- }
-@@ -145,7 +145,7 @@ static int qp_open(struct inode *inode, struct file *file)
-       spin_unlock_irq(&qpd->devp->lock);
-
-       qpd->bufsize = count * 128;
--      qpd->buf = kmalloc(qpd->bufsize, GFP_KERNEL);
-+      qpd->buf = vmalloc(qpd->bufsize);
-       if (!qpd->buf) {
-               ret = -ENOMEM;
-               goto err1;
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/09-RDMA-cxgb4-Remove-kfifo-usage.patch b/linux-next-cherry-picks/09-RDMA-cxgb4-Remove-kfifo-usage.patch
deleted file mode 100644 (file)
index 7988950..0000000
+++ /dev/null
@@ -1,632 +0,0 @@
-From ec3eead217181d7360a11317a888ceb30807867c Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:32 +0530
-Subject: [PATCH 12/13] RDMA/cxgb4: Remove kfifo usage
-
-Using kfifos for ID management was limiting the number of QPs and
-preventing NP384 MPI jobs.  So replace it with a simple bitmap
-allocator.
-
-Remove IDs from the IDR tables before deallocating them.  This bug was
-causing the BUG_ON() in insert_handle() to fire because the ID was
-getting reused before being removed from the IDR table.
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/infiniband/hw/cxgb4/Makefile   |    2 +-
- drivers/infiniband/hw/cxgb4/device.c   |   37 +++++---
- drivers/infiniband/hw/cxgb4/id_table.c |  112 ++++++++++++++++++++++++
- drivers/infiniband/hw/cxgb4/iw_cxgb4.h |   35 ++++++--
- drivers/infiniband/hw/cxgb4/mem.c      |   10 +--
- drivers/infiniband/hw/cxgb4/provider.c |    9 +--
- drivers/infiniband/hw/cxgb4/resource.c |  148 ++++++++------------------------
- 7 files changed, 203 insertions(+), 150 deletions(-)
- create mode 100644 drivers/infiniband/hw/cxgb4/id_table.c
-
-diff --git a/drivers/infiniband/hw/cxgb4/Makefile b/drivers/infiniband/hw/cxgb4/Makefile
-index 46b878c..e11cf72 100644
---- a/drivers/infiniband/hw/cxgb4/Makefile
-+++ b/drivers/infiniband/hw/cxgb4/Makefile
-@@ -2,4 +2,4 @@ ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4
-
- obj-$(CONFIG_INFINIBAND_CXGB4) += iw_cxgb4.o
-
--iw_cxgb4-y :=  device.o cm.o provider.o mem.o cq.o qp.o resource.o ev.o
-+iw_cxgb4-y :=  device.o cm.o provider.o mem.o cq.o qp.o resource.o ev.o id_table.o
-diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
-index 8545629..c8fd1d8 100644
---- a/drivers/infiniband/hw/cxgb4/device.c
-+++ b/drivers/infiniband/hw/cxgb4/device.c
-@@ -252,25 +252,26 @@ static int stats_show(struct seq_file *seq, void *v)
- {
-       struct c4iw_dev *dev = seq->private;
-
--      seq_printf(seq, " Object: %10s %10s %10s\n", "Total", "Current", "Max");
--      seq_printf(seq, "     PDID: %10llu %10llu %10llu\n",
-+      seq_printf(seq, "   Object: %10s %10s %10s %10s\n", "Total", "Current",
-+                 "Max", "Fail");
-+      seq_printf(seq, "     PDID: %10llu %10llu %10llu %10llu\n",
-                       dev->rdev.stats.pd.total, dev->rdev.stats.pd.cur,
--                      dev->rdev.stats.pd.max);
--      seq_printf(seq, "      QID: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.pd.max, dev->rdev.stats.pd.fail);
-+      seq_printf(seq, "      QID: %10llu %10llu %10llu %10llu\n",
-                       dev->rdev.stats.qid.total, dev->rdev.stats.qid.cur,
--                      dev->rdev.stats.qid.max);
--      seq_printf(seq, "   TPTMEM: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.qid.max, dev->rdev.stats.qid.fail);
-+      seq_printf(seq, "   TPTMEM: %10llu %10llu %10llu %10llu\n",
-                       dev->rdev.stats.stag.total, dev->rdev.stats.stag.cur,
--                      dev->rdev.stats.stag.max);
--      seq_printf(seq, "   PBLMEM: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.stag.max, dev->rdev.stats.stag.fail);
-+      seq_printf(seq, "   PBLMEM: %10llu %10llu %10llu %10llu\n",
-                       dev->rdev.stats.pbl.total, dev->rdev.stats.pbl.cur,
--                      dev->rdev.stats.pbl.max);
--      seq_printf(seq, "   RQTMEM: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.pbl.max, dev->rdev.stats.pbl.fail);
-+      seq_printf(seq, "   RQTMEM: %10llu %10llu %10llu %10llu\n",
-                       dev->rdev.stats.rqt.total, dev->rdev.stats.rqt.cur,
--                      dev->rdev.stats.rqt.max);
--      seq_printf(seq, "  OCQPMEM: %10llu %10llu %10llu\n",
-+                      dev->rdev.stats.rqt.max, dev->rdev.stats.rqt.fail);
-+      seq_printf(seq, "  OCQPMEM: %10llu %10llu %10llu %10llu\n",
-                       dev->rdev.stats.ocqp.total, dev->rdev.stats.ocqp.cur,
--                      dev->rdev.stats.ocqp.max);
-+                      dev->rdev.stats.ocqp.max, dev->rdev.stats.ocqp.fail);
-       seq_printf(seq, "  DB FULL: %10llu\n", dev->rdev.stats.db_full);
-       seq_printf(seq, " DB EMPTY: %10llu\n", dev->rdev.stats.db_empty);
-       seq_printf(seq, "  DB DROP: %10llu\n", dev->rdev.stats.db_drop);
-@@ -292,11 +293,17 @@ static ssize_t stats_clear(struct file *file, const char __user *buf,
-
-       mutex_lock(&dev->rdev.stats.lock);
-       dev->rdev.stats.pd.max = 0;
-+      dev->rdev.stats.pd.fail = 0;
-       dev->rdev.stats.qid.max = 0;
-+      dev->rdev.stats.qid.fail = 0;
-       dev->rdev.stats.stag.max = 0;
-+      dev->rdev.stats.stag.fail = 0;
-       dev->rdev.stats.pbl.max = 0;
-+      dev->rdev.stats.pbl.fail = 0;
-       dev->rdev.stats.rqt.max = 0;
-+      dev->rdev.stats.rqt.fail = 0;
-       dev->rdev.stats.ocqp.max = 0;
-+      dev->rdev.stats.ocqp.fail = 0;
-       dev->rdev.stats.db_full = 0;
-       dev->rdev.stats.db_empty = 0;
-       dev->rdev.stats.db_drop = 0;
-@@ -350,8 +357,8 @@ void c4iw_release_dev_ucontext(struct c4iw_rdev *rdev,
-               entry = list_entry(pos, struct c4iw_qid_list, entry);
-               list_del_init(&entry->entry);
-               if (!(entry->qid & rdev->qpmask)) {
--                      c4iw_put_resource(&rdev->resource.qid_fifo, entry->qid,
--                                      &rdev->resource.qid_fifo_lock);
-+                      c4iw_put_resource(&rdev->resource.qid_table,
-+                                        entry->qid);
-                       mutex_lock(&rdev->stats.lock);
-                       rdev->stats.qid.cur -= rdev->qpmask + 1;
-                       mutex_unlock(&rdev->stats.lock);
-diff --git a/drivers/infiniband/hw/cxgb4/id_table.c b/drivers/infiniband/hw/cxgb4/id_table.c
-new file mode 100644
-index 0000000..f95e5df
---- /dev/null
-+++ b/drivers/infiniband/hw/cxgb4/id_table.c
-@@ -0,0 +1,112 @@
-+/*
-+ * Copyright (c) 2011 Chelsio Communications.  All rights reserved.
-+ *
-+ * This software is available to you under a choice of one of two
-+ * licenses.  You may choose to be licensed under the terms of the GNU
-+ * General Public License (GPL) Version 2, available from the file
-+ * COPYING in the main directory of this source tree, or the
-+ * OpenIB.org BSD license below:
-+ *
-+ *     Redistribution and use in source and binary forms, with or
-+ *     without modification, are permitted provided that the following
-+ *     conditions are met:
-+ *
-+ *      - Redistributions of source code must retain the above
-+ *        copyright notice, this list of conditions and the following
-+ *        disclaimer.
-+ *
-+ *      - Redistributions in binary form must reproduce the above
-+ *        copyright notice, this list of conditions and the following
-+ *        disclaimer in the documentation and/or other materials
-+ *        provided with the distribution.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-+ * SOFTWARE.
-+ */
-+#include <linux/kernel.h>
-+#include <linux/random.h>
-+#include "iw_cxgb4.h"
-+
-+#define RANDOM_SKIP 16
-+
-+/*
-+ * Trivial bitmap-based allocator. If the random flag is set, the
-+ * allocator is designed to:
-+ * - pseudo-randomize the id returned such that it is not trivially predictable.
-+ * - avoid reuse of recently used id (at the expense of predictability)
-+ */
-+u32 c4iw_id_alloc(struct c4iw_id_table *alloc)
-+{
-+      unsigned long flags;
-+      u32 obj;
-+
-+      spin_lock_irqsave(&alloc->lock, flags);
-+
-+      obj = find_next_zero_bit(alloc->table, alloc->max, alloc->last);
-+      if (obj >= alloc->max)
-+              obj = find_first_zero_bit(alloc->table, alloc->max);
-+
-+      if (obj < alloc->max) {
-+              if (alloc->flags & C4IW_ID_TABLE_F_RANDOM)
-+                      alloc->last += random32() % RANDOM_SKIP;
-+              else
-+                      alloc->last = obj + 1;
-+              if (alloc->last >= alloc->max)
-+                      alloc->last = 0;
-+              set_bit(obj, alloc->table);
-+              obj += alloc->start;
-+      } else
-+              obj = -1;
-+
-+      spin_unlock_irqrestore(&alloc->lock, flags);
-+      return obj;
-+}
-+
-+void c4iw_id_free(struct c4iw_id_table *alloc, u32 obj)
-+{
-+      unsigned long flags;
-+
-+      obj -= alloc->start;
-+      BUG_ON((int)obj < 0);
-+
-+      spin_lock_irqsave(&alloc->lock, flags);
-+      clear_bit(obj, alloc->table);
-+      spin_unlock_irqrestore(&alloc->lock, flags);
-+}
-+
-+int c4iw_id_table_alloc(struct c4iw_id_table *alloc, u32 start, u32 num,
-+                      u32 reserved, u32 flags)
-+{
-+      int i;
-+
-+      alloc->start = start;
-+      alloc->flags = flags;
-+      if (flags & C4IW_ID_TABLE_F_RANDOM)
-+              alloc->last = random32() % RANDOM_SKIP;
-+      else
-+              alloc->last = 0;
-+      alloc->max  = num;
-+      spin_lock_init(&alloc->lock);
-+      alloc->table = kmalloc(BITS_TO_LONGS(num) * sizeof(long),
-+                              GFP_KERNEL);
-+      if (!alloc->table)
-+              return -ENOMEM;
-+
-+      bitmap_zero(alloc->table, num);
-+      if (!(alloc->flags & C4IW_ID_TABLE_F_EMPTY))
-+              for (i = 0; i < reserved; ++i)
-+                      set_bit(i, alloc->table);
-+
-+      return 0;
-+}
-+
-+void c4iw_id_table_free(struct c4iw_id_table *alloc)
-+{
-+      kfree(alloc->table);
-+}
-diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-index 6818659..2d5b06b 100644
---- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-@@ -45,7 +45,6 @@
- #include <linux/kref.h>
- #include <linux/timer.h>
- #include <linux/io.h>
--#include <linux/kfifo.h>
-
- #include <asm/byteorder.h>
-
-@@ -79,13 +78,22 @@ static inline void *cplhdr(struct sk_buff *skb)
-       return skb->data;
- }
-
-+#define C4IW_ID_TABLE_F_RANDOM 1       /* Pseudo-randomize the id's returned */
-+#define C4IW_ID_TABLE_F_EMPTY  2       /* Table is initially empty */
-+
-+struct c4iw_id_table {
-+      u32 flags;
-+      u32 start;              /* logical minimal id */
-+      u32 last;               /* hint for find */
-+      u32 max;
-+      spinlock_t lock;
-+      unsigned long *table;
-+};
-+
- struct c4iw_resource {
--      struct kfifo tpt_fifo;
--      spinlock_t tpt_fifo_lock;
--      struct kfifo qid_fifo;
--      spinlock_t qid_fifo_lock;
--      struct kfifo pdid_fifo;
--      spinlock_t pdid_fifo_lock;
-+      struct c4iw_id_table tpt_table;
-+      struct c4iw_id_table qid_table;
-+      struct c4iw_id_table pdid_table;
- };
-
- struct c4iw_qid_list {
-@@ -107,6 +115,7 @@ struct c4iw_stat {
-       u64 total;
-       u64 cur;
-       u64 max;
-+      u64 fail;
- };
-
- struct c4iw_stats {
-@@ -253,7 +262,7 @@ static inline int _insert_handle(struct c4iw_dev *rhp, struct idr *idr,
-               if (lock)
-                       spin_lock_irq(&rhp->lock);
-               ret = idr_get_new_above(idr, handle, id, &newid);
--              BUG_ON(newid != id);
-+              BUG_ON(!ret && newid != id);
-               if (lock)
-                       spin_unlock_irq(&rhp->lock);
-       } while (ret == -EAGAIN);
-@@ -755,14 +764,20 @@ static inline int compute_wscale(int win)
-       return wscale;
- }
-
-+u32 c4iw_id_alloc(struct c4iw_id_table *alloc);
-+void c4iw_id_free(struct c4iw_id_table *alloc, u32 obj);
-+int c4iw_id_table_alloc(struct c4iw_id_table *alloc, u32 start, u32 num,
-+                      u32 reserved, u32 flags);
-+void c4iw_id_table_free(struct c4iw_id_table *alloc);
-+
- typedef int (*c4iw_handler_func)(struct c4iw_dev *dev, struct sk_buff *skb);
-
- int c4iw_ep_redirect(void *ctx, struct dst_entry *old, struct dst_entry *new,
-                    struct l2t_entry *l2t);
- void c4iw_put_qpid(struct c4iw_rdev *rdev, u32 qpid,
-                  struct c4iw_dev_ucontext *uctx);
--u32 c4iw_get_resource(struct kfifo *fifo, spinlock_t *lock);
--void c4iw_put_resource(struct kfifo *fifo, u32 entry, spinlock_t *lock);
-+u32 c4iw_get_resource(struct c4iw_id_table *id_table);
-+void c4iw_put_resource(struct c4iw_id_table *id_table, u32 entry);
- int c4iw_init_resource(struct c4iw_rdev *rdev, u32 nr_tpt, u32 nr_pdid);
- int c4iw_init_ctrl_qp(struct c4iw_rdev *rdev);
- int c4iw_pblpool_create(struct c4iw_rdev *rdev);
-diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
-index 2a87379..57e07c6 100644
---- a/drivers/infiniband/hw/cxgb4/mem.c
-+++ b/drivers/infiniband/hw/cxgb4/mem.c
-@@ -131,8 +131,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
-       stag_idx = (*stag) >> 8;
-
-       if ((!reset_tpt_entry) && (*stag == T4_STAG_UNSET)) {
--              stag_idx = c4iw_get_resource(&rdev->resource.tpt_fifo,
--                                           &rdev->resource.tpt_fifo_lock);
-+              stag_idx = c4iw_get_resource(&rdev->resource.tpt_table);
-               if (!stag_idx)
-                       return -ENOMEM;
-               mutex_lock(&rdev->stats.lock);
-@@ -171,8 +170,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
-                               sizeof(tpt), &tpt);
-
-       if (reset_tpt_entry) {
--              c4iw_put_resource(&rdev->resource.tpt_fifo, stag_idx,
--                                &rdev->resource.tpt_fifo_lock);
-+              c4iw_put_resource(&rdev->resource.tpt_table, stag_idx);
-               mutex_lock(&rdev->stats.lock);
-               rdev->stats.stag.cur -= 32;
-               mutex_unlock(&rdev->stats.lock);
-@@ -695,8 +693,8 @@ int c4iw_dealloc_mw(struct ib_mw *mw)
-       mhp = to_c4iw_mw(mw);
-       rhp = mhp->rhp;
-       mmid = (mw->rkey) >> 8;
--      deallocate_window(&rhp->rdev, mhp->attr.stag);
-       remove_handle(rhp, &rhp->mmidr, mmid);
-+      deallocate_window(&rhp->rdev, mhp->attr.stag);
-       kfree(mhp);
-       PDBG("%s ib_mw %p mmid 0x%x ptr %p\n", __func__, mw, mmid, mhp);
-       return 0;
-@@ -798,12 +796,12 @@ int c4iw_dereg_mr(struct ib_mr *ib_mr)
-       mhp = to_c4iw_mr(ib_mr);
-       rhp = mhp->rhp;
-       mmid = mhp->attr.stag >> 8;
-+      remove_handle(rhp, &rhp->mmidr, mmid);
-       dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
-                      mhp->attr.pbl_addr);
-       if (mhp->attr.pbl_size)
-               c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
-                                 mhp->attr.pbl_size << 3);
--      remove_handle(rhp, &rhp->mmidr, mmid);
-       if (mhp->kva)
-               kfree((void *) (unsigned long) mhp->kva);
-       if (mhp->umem)
-diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
-index 8d58736..fe98a0a 100644
---- a/drivers/infiniband/hw/cxgb4/provider.c
-+++ b/drivers/infiniband/hw/cxgb4/provider.c
-@@ -188,8 +188,7 @@ static int c4iw_deallocate_pd(struct ib_pd *pd)
-       php = to_c4iw_pd(pd);
-       rhp = php->rhp;
-       PDBG("%s ibpd %p pdid 0x%x\n", __func__, pd, php->pdid);
--      c4iw_put_resource(&rhp->rdev.resource.pdid_fifo, php->pdid,
--                        &rhp->rdev.resource.pdid_fifo_lock);
-+      c4iw_put_resource(&rhp->rdev.resource.pdid_table, php->pdid);
-       mutex_lock(&rhp->rdev.stats.lock);
-       rhp->rdev.stats.pd.cur--;
-       mutex_unlock(&rhp->rdev.stats.lock);
-@@ -207,14 +206,12 @@ static struct ib_pd *c4iw_allocate_pd(struct ib_device *ibdev,
-
-       PDBG("%s ibdev %p\n", __func__, ibdev);
-       rhp = (struct c4iw_dev *) ibdev;
--      pdid =  c4iw_get_resource(&rhp->rdev.resource.pdid_fifo,
--                                &rhp->rdev.resource.pdid_fifo_lock);
-+      pdid =  c4iw_get_resource(&rhp->rdev.resource.pdid_table);
-       if (!pdid)
-               return ERR_PTR(-EINVAL);
-       php = kzalloc(sizeof(*php), GFP_KERNEL);
-       if (!php) {
--              c4iw_put_resource(&rhp->rdev.resource.pdid_fifo, pdid,
--                                &rhp->rdev.resource.pdid_fifo_lock);
-+              c4iw_put_resource(&rhp->rdev.resource.pdid_table, pdid);
-               return ERR_PTR(-ENOMEM);
-       }
-       php->pdid = pdid;
-diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c
-index 1b948d1..cdef4d7 100644
---- a/drivers/infiniband/hw/cxgb4/resource.c
-+++ b/drivers/infiniband/hw/cxgb4/resource.c
-@@ -30,96 +30,25 @@
-  * SOFTWARE.
-  */
- /* Crude resource management */
--#include <linux/kernel.h>
--#include <linux/random.h>
--#include <linux/slab.h>
--#include <linux/kfifo.h>
- #include <linux/spinlock.h>
--#include <linux/errno.h>
- #include <linux/genalloc.h>
- #include <linux/ratelimit.h>
- #include "iw_cxgb4.h"
-
--#define RANDOM_SIZE 16
--
--static int __c4iw_init_resource_fifo(struct kfifo *fifo,
--                                 spinlock_t *fifo_lock,
--                                 u32 nr, u32 skip_low,
--                                 u32 skip_high,
--                                 int random)
--{
--      u32 i, j, entry = 0, idx;
--      u32 random_bytes;
--      u32 rarray[16];
--      spin_lock_init(fifo_lock);
--
--      if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL))
--              return -ENOMEM;
--
--      for (i = 0; i < skip_low + skip_high; i++)
--              kfifo_in(fifo, (unsigned char *) &entry, sizeof(u32));
--      if (random) {
--              j = 0;
--              random_bytes = random32();
--              for (i = 0; i < RANDOM_SIZE; i++)
--                      rarray[i] = i + skip_low;
--              for (i = skip_low + RANDOM_SIZE; i < nr - skip_high; i++) {
--                      if (j >= RANDOM_SIZE) {
--                              j = 0;
--                              random_bytes = random32();
--                      }
--                      idx = (random_bytes >> (j * 2)) & 0xF;
--                      kfifo_in(fifo,
--                              (unsigned char *) &rarray[idx],
--                              sizeof(u32));
--                      rarray[idx] = i;
--                      j++;
--              }
--              for (i = 0; i < RANDOM_SIZE; i++)
--                      kfifo_in(fifo,
--                              (unsigned char *) &rarray[i],
--                              sizeof(u32));
--      } else
--              for (i = skip_low; i < nr - skip_high; i++)
--                      kfifo_in(fifo, (unsigned char *) &i, sizeof(u32));
--
--      for (i = 0; i < skip_low + skip_high; i++)
--              if (kfifo_out_locked(fifo, (unsigned char *) &entry,
--                                   sizeof(u32), fifo_lock))
--                      break;
--      return 0;
--}
--
--static int c4iw_init_resource_fifo(struct kfifo *fifo, spinlock_t * fifo_lock,
--                                 u32 nr, u32 skip_low, u32 skip_high)
--{
--      return __c4iw_init_resource_fifo(fifo, fifo_lock, nr, skip_low,
--                                        skip_high, 0);
--}
--
--static int c4iw_init_resource_fifo_random(struct kfifo *fifo,
--                                 spinlock_t *fifo_lock,
--                                 u32 nr, u32 skip_low, u32 skip_high)
--{
--      return __c4iw_init_resource_fifo(fifo, fifo_lock, nr, skip_low,
--                                        skip_high, 1);
--}
--
--static int c4iw_init_qid_fifo(struct c4iw_rdev *rdev)
-+static int c4iw_init_qid_table(struct c4iw_rdev *rdev)
- {
-       u32 i;
-
--      spin_lock_init(&rdev->resource.qid_fifo_lock);
--
--      if (kfifo_alloc(&rdev->resource.qid_fifo, rdev->lldi.vr->qp.size *
--                      sizeof(u32), GFP_KERNEL))
-+      if (c4iw_id_table_alloc(&rdev->resource.qid_table,
-+                              rdev->lldi.vr->qp.start,
-+                              rdev->lldi.vr->qp.size,
-+                              rdev->lldi.vr->qp.size, 0))
-               return -ENOMEM;
-
-       for (i = rdev->lldi.vr->qp.start;
--           i < rdev->lldi.vr->qp.start + rdev->lldi.vr->qp.size; i++)
-+              i < rdev->lldi.vr->qp.start + rdev->lldi.vr->qp.size; i++)
-               if (!(i & rdev->qpmask))
--                      kfifo_in(&rdev->resource.qid_fifo,
--                                  (unsigned char *) &i, sizeof(u32));
-+                      c4iw_id_free(&rdev->resource.qid_table, i);
-       return 0;
- }
-
-@@ -127,44 +56,42 @@ static int c4iw_init_qid_fifo(struct c4iw_rdev *rdev)
- int c4iw_init_resource(struct c4iw_rdev *rdev, u32 nr_tpt, u32 nr_pdid)
- {
-       int err = 0;
--      err = c4iw_init_resource_fifo_random(&rdev->resource.tpt_fifo,
--                                           &rdev->resource.tpt_fifo_lock,
--                                           nr_tpt, 1, 0);
-+      err = c4iw_id_table_alloc(&rdev->resource.tpt_table, 0, nr_tpt, 1,
-+                                      C4IW_ID_TABLE_F_RANDOM);
-       if (err)
-               goto tpt_err;
--      err = c4iw_init_qid_fifo(rdev);
-+      err = c4iw_init_qid_table(rdev);
-       if (err)
-               goto qid_err;
--      err = c4iw_init_resource_fifo(&rdev->resource.pdid_fifo,
--                                    &rdev->resource.pdid_fifo_lock,
--                                    nr_pdid, 1, 0);
-+      err = c4iw_id_table_alloc(&rdev->resource.pdid_table, 0,
-+                                      nr_pdid, 1, 0);
-       if (err)
-               goto pdid_err;
-       return 0;
--pdid_err:
--      kfifo_free(&rdev->resource.qid_fifo);
--qid_err:
--      kfifo_free(&rdev->resource.tpt_fifo);
--tpt_err:
-+ pdid_err:
-+      c4iw_id_table_free(&rdev->resource.qid_table);
-+ qid_err:
-+      c4iw_id_table_free(&rdev->resource.tpt_table);
-+ tpt_err:
-       return -ENOMEM;
- }
-
- /*
-  * returns 0 if no resource available
-  */
--u32 c4iw_get_resource(struct kfifo *fifo, spinlock_t *lock)
-+u32 c4iw_get_resource(struct c4iw_id_table *id_table)
- {
-       u32 entry;
--      if (kfifo_out_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock))
--              return entry;
--      else
-+      entry = c4iw_id_alloc(id_table);
-+      if (entry == (u32)(-1))
-               return 0;
-+      return entry;
- }
-
--void c4iw_put_resource(struct kfifo *fifo, u32 entry, spinlock_t *lock)
-+void c4iw_put_resource(struct c4iw_id_table *id_table, u32 entry)
- {
-       PDBG("%s entry 0x%x\n", __func__, entry);
--      kfifo_in_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock);
-+      c4iw_id_free(id_table, entry);
- }
-
- u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
-@@ -181,8 +108,7 @@ u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
-               qid = entry->qid;
-               kfree(entry);
-       } else {
--              qid = c4iw_get_resource(&rdev->resource.qid_fifo,
--                                      &rdev->resource.qid_fifo_lock);
-+              qid = c4iw_get_resource(&rdev->resource.qid_table);
-               if (!qid)
-                       goto out;
-               mutex_lock(&rdev->stats.lock);
-@@ -252,8 +178,7 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
-               qid = entry->qid;
-               kfree(entry);
-       } else {
--              qid = c4iw_get_resource(&rdev->resource.qid_fifo,
--                                      &rdev->resource.qid_fifo_lock);
-+              qid = c4iw_get_resource(&rdev->resource.qid_table);
-               if (!qid)
-                       goto out;
-               mutex_lock(&rdev->stats.lock);
-@@ -311,9 +236,9 @@ void c4iw_put_qpid(struct c4iw_rdev *rdev, u32 qid,
-
- void c4iw_destroy_resource(struct c4iw_resource *rscp)
- {
--      kfifo_free(&rscp->tpt_fifo);
--      kfifo_free(&rscp->qid_fifo);
--      kfifo_free(&rscp->pdid_fifo);
-+      c4iw_id_table_free(&rscp->tpt_table);
-+      c4iw_id_table_free(&rscp->qid_table);
-+      c4iw_id_table_free(&rscp->pdid_table);
- }
-
- /*
-@@ -326,16 +251,14 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size)
- {
-       unsigned long addr = gen_pool_alloc(rdev->pbl_pool, size);
-       PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size);
--      if (!addr)
--              printk_ratelimited(KERN_WARNING MOD "%s: Out of PBL memory\n",
--                     pci_name(rdev->lldi.pdev));
-+      mutex_lock(&rdev->stats.lock);
-       if (addr) {
--              mutex_lock(&rdev->stats.lock);
-               rdev->stats.pbl.cur += roundup(size, 1 << MIN_PBL_SHIFT);
-               if (rdev->stats.pbl.cur > rdev->stats.pbl.max)
-                       rdev->stats.pbl.max = rdev->stats.pbl.cur;
--              mutex_unlock(&rdev->stats.lock);
--      }
-+      } else
-+              rdev->stats.pbl.fail++;
-+      mutex_unlock(&rdev->stats.lock);
-       return (u32)addr;
- }
-
-@@ -401,13 +324,14 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size)
-       if (!addr)
-               printk_ratelimited(KERN_WARNING MOD "%s: Out of RQT memory\n",
-                      pci_name(rdev->lldi.pdev));
-+      mutex_lock(&rdev->stats.lock);
-       if (addr) {
--              mutex_lock(&rdev->stats.lock);
-               rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT);
-               if (rdev->stats.rqt.cur > rdev->stats.rqt.max)
-                       rdev->stats.rqt.max = rdev->stats.rqt.cur;
--              mutex_unlock(&rdev->stats.lock);
--      }
-+      } else
-+              rdev->stats.rqt.fail++;
-+      mutex_unlock(&rdev->stats.lock);
-       return (u32)addr;
- }
-
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/10-RDMA-cxgb4-Add-query_qp-support.patch b/linux-next-cherry-picks/10-RDMA-cxgb4-Add-query_qp-support.patch
deleted file mode 100644 (file)
index 644c6b7..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-From 67bbc05512d8a609e9a2d284dbfda9d2c50f0bf6 Mon Sep 17 00:00:00 2001
-From: Vipul Pandya <vipul@chelsio.com>
-Date: Fri, 18 May 2012 15:29:33 +0530
-Subject: [PATCH 13/13] RDMA/cxgb4: Add query_qp support
-
-This allows querying the QP state before flushing.
-
-Signed-off-by: Vipul Pandya <vipul@chelsio.com>
-Signed-off-by: Steve Wise <swise@opengridcomputing.com>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/infiniband/hw/cxgb4/iw_cxgb4.h |   19 +++++++++++++++++++
- drivers/infiniband/hw/cxgb4/provider.c |    2 ++
- drivers/infiniband/hw/cxgb4/qp.c       |   11 +++++++++++
- 3 files changed, 32 insertions(+), 0 deletions(-)
-
-diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-index 2d5b06b..9beb3a9 100644
---- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
-@@ -551,6 +551,23 @@ static inline int c4iw_convert_state(enum ib_qp_state ib_state)
-       }
- }
-
-+static inline int to_ib_qp_state(int c4iw_qp_state)
-+{
-+      switch (c4iw_qp_state) {
-+      case C4IW_QP_STATE_IDLE:
-+              return IB_QPS_INIT;
-+      case C4IW_QP_STATE_RTS:
-+              return IB_QPS_RTS;
-+      case C4IW_QP_STATE_CLOSING:
-+              return IB_QPS_SQD;
-+      case C4IW_QP_STATE_TERMINATE:
-+              return IB_QPS_SQE;
-+      case C4IW_QP_STATE_ERROR:
-+              return IB_QPS_ERR;
-+      }
-+      return IB_QPS_ERR;
-+}
-+
- static inline u32 c4iw_ib_to_tpt_access(int a)
- {
-       return (a & IB_ACCESS_REMOTE_WRITE ? FW_RI_MEM_ACCESS_REM_WRITE : 0) |
-@@ -846,6 +863,8 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd,
-                            struct ib_udata *udata);
- int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
-                                int attr_mask, struct ib_udata *udata);
-+int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
-+                   int attr_mask, struct ib_qp_init_attr *init_attr);
- struct ib_qp *c4iw_get_qp(struct ib_device *dev, int qpn);
- u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size);
- void c4iw_rqtpool_free(struct c4iw_rdev *rdev, u32 addr, int size);
-diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
-index fe98a0a..e084fdc 100644
---- a/drivers/infiniband/hw/cxgb4/provider.c
-+++ b/drivers/infiniband/hw/cxgb4/provider.c
-@@ -443,6 +443,7 @@ int c4iw_register_device(struct c4iw_dev *dev)
-           (1ull << IB_USER_VERBS_CMD_REQ_NOTIFY_CQ) |
-           (1ull << IB_USER_VERBS_CMD_CREATE_QP) |
-           (1ull << IB_USER_VERBS_CMD_MODIFY_QP) |
-+          (1ull << IB_USER_VERBS_CMD_QUERY_QP) |
-           (1ull << IB_USER_VERBS_CMD_POLL_CQ) |
-           (1ull << IB_USER_VERBS_CMD_DESTROY_QP) |
-           (1ull << IB_USER_VERBS_CMD_POST_SEND) |
-@@ -465,6 +466,7 @@ int c4iw_register_device(struct c4iw_dev *dev)
-       dev->ibdev.destroy_ah = c4iw_ah_destroy;
-       dev->ibdev.create_qp = c4iw_create_qp;
-       dev->ibdev.modify_qp = c4iw_ib_modify_qp;
-+      dev->ibdev.query_qp = c4iw_ib_query_qp;
-       dev->ibdev.destroy_qp = c4iw_destroy_qp;
-       dev->ibdev.create_cq = c4iw_create_cq;
-       dev->ibdev.destroy_cq = c4iw_destroy_cq;
-diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
-index ba1343e..45aedf1 100644
---- a/drivers/infiniband/hw/cxgb4/qp.c
-+++ b/drivers/infiniband/hw/cxgb4/qp.c
-@@ -1711,3 +1711,14 @@ struct ib_qp *c4iw_get_qp(struct ib_device *dev, int qpn)
-       PDBG("%s ib_dev %p qpn 0x%x\n", __func__, dev, qpn);
-       return (struct ib_qp *)get_qhp(to_c4iw_dev(dev), qpn);
- }
-+
-+int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
-+                   int attr_mask, struct ib_qp_init_attr *init_attr)
-+{
-+      struct c4iw_qp *qhp = to_c4iw_qp(ibqp);
-+
-+      memset(attr, 0, sizeof *attr);
-+      memset(init_attr, 0, sizeof *init_attr);
-+      attr->qp_state = to_ib_qp_state(qhp->attr.state);
-+      return 0;
-+}
---
-1.7.1
-
diff --git a/linux-next-cherry-picks/11-IB-mlx4-pass-SMP-vendor-specific-attribute-MADs-to-f.patch b/linux-next-cherry-picks/11-IB-mlx4-pass-SMP-vendor-specific-attribute-MADs-to-f.patch
deleted file mode 100644 (file)
index b804a33..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-From a6f7feae6d19e84253918d88b04153af09d3a243 Mon Sep 17 00:00:00 2001
-From: Jack Morgenstein <jackm@mellanox.com>
-Date: Thu, 26 Jan 2012 16:41:33 +0200
-Subject: [PATCH] IB/mlx4: pass SMP vendor-specific attribute MADs to firmware
-
-In the current code, vendor-specific MADs (e.g with the FDR-10
-attribute) are silently dropped by the driver, resulting in timeouts
-at the sending side and inability to query/configure the relevant
-feature.  However, the ConnectX firmware is able to handle such MADs.
-For unsupported attributes, the firmware returns a GET_RESPONSE MAD
-containing an error status.
-
-For example, for a FDR-10 node with LID 11:
-
-    # ibstat mlx4_0 1
-
-    CA: 'mlx4_0'
-    Port 1:
-    State: Active
-    Physical state: LinkUp
-    Rate: 40 (FDR10)
-    Base lid: 11
-    LMC: 0
-    SM lid: 24
-    Capability mask: 0x02514868
-    Port GUID: 0x0002c903002e65d1
-    Link layer: InfiniBand
-
-Extended Port Query (EPI) vendor mad timeouts before the patch:
-
-    # smpquery MEPI 11 -d
-
-    ibwarn: [4196] smp_query_via: attr 0xff90 mod 0x0 route Lid 11
-    ibwarn: [4196] _do_madrpc: retry 1 (timeout 1000 ms)
-    ibwarn: [4196] _do_madrpc: retry 2 (timeout 1000 ms)
-    ibwarn: [4196] _do_madrpc: timeout after 3 retries, 3000 ms
-    ibwarn: [4196] mad_rpc: _do_madrpc failed; dport (Lid 11)
-    smpquery: iberror: [pid 4196] main: failed: operation EPI: ext port info query failed
-
-EPI query works OK with the patch:
-
-    # smpquery MEPI 11 -d
-
-    ibwarn: [6548] smp_query_via: attr 0xff90 mod 0x0 route Lid 11
-    ibwarn: [6548] mad_rpc: data offs 64 sz 64
-    mad data
-    0000 0000 0000 0001 0000 0001 0000 0001
-    0000 0000 0000 0000 0000 0000 0000 0000
-    0000 0000 0000 0000 0000 0000 0000 0000
-    0000 0000 0000 0000 0000 0000 0000 0000
-    # Ext Port info: Lid 11 port 0
-    StateChangeEnable:...............0x00
-    LinkSpeedSupported:..............0x01
-    LinkSpeedEnabled:................0x01
-    LinkSpeedActive:.................0x01
-
-Signed-off-by: Jack Morgenstein <jackm@mellanox.com>
-Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
-Acked-by: Ira Weiny <weiny2@llnl.gov>
-Cc: <stable@vger.kernel.org>
-Signed-off-by: Roland Dreier <roland@purestorage.com>
----
- drivers/infiniband/hw/mlx4/mad.c |    7 ++-----
- 1 files changed, 2 insertions(+), 5 deletions(-)
-
-diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c
-index 95c94d8..259b067 100644
---- a/drivers/infiniband/hw/mlx4/mad.c
-+++ b/drivers/infiniband/hw/mlx4/mad.c
-@@ -257,12 +257,9 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
-                       return IB_MAD_RESULT_SUCCESS;
-               /*
--               * Don't process SMInfo queries or vendor-specific
--               * MADs -- the SMA can't handle them.
-+               * Don't process SMInfo queries -- the SMA can't handle them.
-                */
--              if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO ||
--                  ((in_mad->mad_hdr.attr_id & IB_SMP_ATTR_VENDOR_MASK) ==
--                   IB_SMP_ATTR_VENDOR_MASK))
-+              if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO)
-                       return IB_MAD_RESULT_SUCCESS;
-       } else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT ||
-                  in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1   ||
--- 
-1.7.0.4
-