Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-12 Thread Ralph Campbell
On Fri, 2010-04-09 at 17:27 -0700, Jason Gunthorpe wrote:
 On Fri, Apr 09, 2010 at 05:13:24PM -0700, Ralph Campbell wrote:
 
  For the QSFP data, I hope I can leave it as is since it is
  related to the link state that the other files contain.
  It is a read-only file so no issue with trying to set a value.
 
 There was some flack for other stuff like this a while back.
 
 IMHO, it would be appropriate to have a hex dump of the entire QFSP
 EEPROM and leave parsing to userspace, or put the parsed version in
 debugfs..
 
 Jason

OK. I will move it to our file system which is used
to export binary data.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-09 Thread Ralph Campbell
On Thu, 2010-04-08 at 15:50 -0700, Jason Gunthorpe wrote:
 On Thu, Apr 08, 2010 at 03:26:41PM -0700, Ralph Campbell wrote:
  On Thu, 2010-04-08 at 15:08 -0700, Jason Gunthorpe wrote:
   On Thu, Apr 08, 2010 at 02:29:53PM -0700, Ralph Campbell wrote:
   
One other place that has multiple values is dumping the QSFP
data from the IB cable.
   
   I was going to comment that building your own I2C subsystem is kinda
   strange, can't the in-kernel stuff be used?
 
  It is a bit strange but we have had this discussion before with
  the ib_ipath driver. Basically, the devices connected to the bus
  weren't really I2C compliant. Since we had to support the
  non-standard parts, it was easier to have only one set of code
  that could handle both.
 
 Is this still true on qib? I didn't notice anything too obviously
 weird, and QSFPs are clearly standard i2c..
 
 The i2c layer has a pretty flexible definition of i2c these days..
 
 Jason

I would be very reluctant to change this code.
One device we have doesn't have an i2c address, the address is the
address of memory within the chip, not the address of the chip on the
bus.

Reading some of the QSFP cable's EEPROM caused another EEPROM
on the bus to be erased. We had to put in defensive code to
check for this case.

I'm not the expert who wrote this code (he retired) so I would have
to do a lot of work making sure the older parts and cables with
these problems worked after a major rewrite of the code.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-09 Thread Ralph Campbell
On Thu, 2010-04-08 at 14:33 -0700, Roland Dreier wrote:
  This was for debugging and clearly could use a better method.
   Some stats are definitely useful and having files per value
   would make scripting easier too.
   I could add /sys/class/infiniband/qib0/ports/1/diag_counters/*
   
   One other place that has multiple values is dumping the QSFP
   data from the IB cable.
 
 You can stick debugging data under debugfs.  Or just kill it for now and
 figure out how to add it back later.

OK. I replaced the /sys/class/infiniband/qib0/stats file with

% ls /sys/class/infiniband/qib0/ports/1/diag_counters/
dmawait pkt_dropsrc_dupreq   rc_seqnakrnr_naks
loop_pkts   rc_acks  rc_qacksrc_timeouts  seq_naks
other_naks  rc_delayed_comp  rc_resends  rdma_seq unaligned

These are all simple counter values.

For the QSFP data, I hope I can leave it as is since it is
related to the link state that the other files contain.
It is a read-only file so no issue with trying to set a value.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 12/51] IB/qib: Add qib_dma.c

2010-04-08 Thread Ralph Campbell
OK. This will be in v3.

On Wed, 2010-03-31 at 16:18 -0700, Roland Dreier wrote:
  +struct ib_dma_mapping_ops qib_dma_mapping_ops = {
   +  qib_mapping_error,
   +  qib_dma_map_single,
   +  qib_dma_unmap_single,
   +  qib_dma_map_page,
   +  qib_dma_unmap_page,
   +  qib_map_sg,
   +  qib_unmap_sg,
   +  qib_sg_dma_address,
   +  qib_sg_dma_len,
   +  qib_sync_single_for_cpu,
   +  qib_sync_single_for_device,
   +  qib_dma_alloc_coherent,
   +  qib_dma_free_coherent
   +};
 
 I think it would be better to use designated initializers (.xxx = yyy,)
 here to avoid problems if this struct ever changes layout.


--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-08 Thread Ralph Campbell
This was for debugging and clearly could use a better method.
Some stats are definitely useful and having files per value
would make scripting easier too.
I could add /sys/class/infiniband/qib0/ports/1/diag_counters/*

One other place that has multiple values is dumping the QSFP
data from the IB cable.

On Thu, 2010-04-08 at 13:50 -0700, Roland Dreier wrote:
 I didn't audit everything (so there may be more problems here too), but
 certainly this violates the one value per sysfs file rule rather
 egregiously:
 
   +static ssize_t show_stats(struct device *device, struct device_attribute 
 *attr,
   +char *buf)
   +{
   +  struct qib_ibdev *dev =
   +  container_of(device, struct qib_ibdev, ibdev.dev);
   +  struct qib_devdata *dd = dd_from_dev(dev);
   +  unsigned pidx;
   +  unsigned i;
   +  int len = 0;
   +  unsigned long flags;
   +
   +  for (pidx = 0; pidx  dd-num_pports; ++pidx) {
   +  struct qib_ibport *ibp = dd-pport[pidx].ibport_data;
   +
   +  len += sprintf(buf + len,
   + Port %d:\n
   + RC timeouts %d\n
   + RC resends  %d\n
   + RC QACKs%d\n
   + RC SEQ NAKs %d\n
   + RC RDMA seq %d\n
   + RC RNR NAKs %d\n
   + RC OTH NAKs %d\n
   + RC DComp%d\n
   + RCr dup req %d\n
   + RCr SEQ NAK %d\n
   + wait piobuf %d\n
   + wait DMA%d\n
   + wait TX %d\n
   + unaligned   %d\n
   + loop pkts   %d\n
   + PKT drops   %d\n,
   + dd-pport[pidx].port,
   + ibp-n_timeouts, ibp-n_rc_resends,
   + ibp-n_rc_qacks, ibp-n_seq_naks,
   + ibp-n_rdma_seq, ibp-n_rnr_naks,
   + ibp-n_other_naks, ibp-n_rc_delayed_comp,
   + ibp-n_rc_dupreq, ibp-n_rc_seqnak,
   + dev-n_piowait, ibp-n_dmawait, dev-n_txwait,
   + ibp-n_unaligned, ibp-n_loop_pkts,
   + ibp-n_pkt_drops);
   +  for (i = 0; i  ARRAY_SIZE(ibp-opstats); i++) {
   +  const struct qib_opcode_stats *si = ibp-opstats[i];
   +
   +  if (!si-n_packets  !si-n_bytes)
   +  continue;
   +  len += sprintf(buf + len, %02x %llu/%llu\n, i,
   + (unsigned long long) si-n_packets,
   + (unsigned long long) si-n_bytes);
   +  }
   +  }
   +  len += sprintf(buf + len, Ctx:npkts);
   +  for (i = 0; i  dd-first_user_ctxt; i++) {
   +  if (!dd-rcd[i])
   +  continue;
   +  len += sprintf(buf + len,  %u:%u, i,
   + dd-rcd[i]-pkt_count);
   +  }
   +  len += sprintf(buf + len, \n);
   +  spin_lock_irqsave(dev-qpt_lock, flags);
   +  for (i = 0; i  dev-qp_table_size; i++) {
   +  struct qib_qp *qp;
   +  for (qp = dev-qp_table[i]; qp != NULL; qp = qp-next) {
   +  struct qib_swqe *wqe;
   +
   +  if (qp-s_last == qp-s_acked 
   +  qp-s_acked == qp-s_cur 
   +  qp-s_cur == qp-s_tail 
   +  qp-s_tail == qp-s_head)
   +  continue;
   +  if (len + 128 = PAGE_SIZE)
   +  break;
   +  wqe = get_swqe_ptr(qp, qp-s_last);
   +  len += sprintf(buf + len,
   + QP%u %s %u %u %u f=%x %u %u %u %u %u 
   + PSN %x %x %x %x %x 
   + (%u %u %u %u %u %u) QP%u LID %x\n,
   + qp-ibqp.qp_num,
   + qp_type_str[qp-ibqp.qp_type],
   + qp-state,
   + wqe-wr.opcode,
   + qp-s_hdrwords,
   + qp-s_flags,
   + atomic_read(qp-s_dma_busy),
   + !list_empty(qp-iowait),
   + qp-timeout,
   + wqe-ssn,
   + qp-s_lsn,
   + qp-s_last_psn,
   + qp-s_psn, qp-s_next_psn,
   + qp-s_sending_psn, qp-s_sending_hpsn,
   + qp-s_last, qp-s_acked, qp-s_cur,
   + qp-s_tail, qp-s_head, qp-s_size,
   + qp-remote_qpn,
   +

Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-08 Thread Ralph Campbell
On Thu, 2010-04-08 at 15:08 -0700, Jason Gunthorpe wrote:
 On Thu, Apr 08, 2010 at 02:29:53PM -0700, Ralph Campbell wrote:
 
  One other place that has multiple values is dumping the QSFP
  data from the IB cable.
 
 I was going to comment that building your own I2C subsystem is kinda
 strange, can't the in-kernel stuff be used?
 
 Jason

It is a bit strange but we have had this discussion before with
the ib_ipath driver. Basically, the devices connected to the bus
weren't really I2C compliant. Since we had to support the
non-standard parts, it was easier to have only one set of code
that could handle both.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2010-04-08 Thread Ralph Campbell
On Thu, 2010-04-08 at 15:50 -0700, Jason Gunthorpe wrote:
 On Thu, Apr 08, 2010 at 03:26:41PM -0700, Ralph Campbell wrote:
  On Thu, 2010-04-08 at 15:08 -0700, Jason Gunthorpe wrote:
   On Thu, Apr 08, 2010 at 02:29:53PM -0700, Ralph Campbell wrote:
   
One other place that has multiple values is dumping the QSFP
data from the IB cable.
   
   I was going to comment that building your own I2C subsystem is kinda
   strange, can't the in-kernel stuff be used?
 
  It is a bit strange but we have had this discussion before with
  the ib_ipath driver. Basically, the devices connected to the bus
  weren't really I2C compliant. Since we had to support the
  non-standard parts, it was easier to have only one set of code
  that could handle both.
 
 Is this still true on qib? I didn't notice anything too obviously
 weird, and QSFPs are clearly standard i2c..
 
 The i2c layer has a pretty flexible definition of i2c these days..
 
 Jason

I will take another look but don't be surprised if it takes me
awhile since I'm also working on addressing the other comments
too.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] best practice for setting IB_CQ_REPORT_MISSED_EVENTS

2010-03-31 Thread Ralph Campbell
The following patches update ISER, SRP and core to use the
IB_CQ_REPORT_MISSED_EVENTS when calling ib_req_notify_cq()
similar to the patch I sent out for RDS.

Since the QLogic HCAs use a separate thread to generate the CQ callback,
it is important to make sure it isn't delayed more than necessary.
--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] IB/iser: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-31 Thread Ralph Campbell
ib_req_notify_cq(IB_CQ_NEXT_COMP) is not guaranteed to generate
a callback for the next completion entered since there is a race
between arming the callback and another CQE being added to the queue.
The IB_CQ_REPORT_MISSED_EVENTS flag was added to detect this
race and allow the verbs consumer to call ib_poll_cq() and
ib_req_notify_cq() again to avoid delays in processing the CQE.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/ulp/iser/iser_verbs.c |   10 +++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c 
b/drivers/infiniband/ulp/iser/iser_verbs.c
index 308d17b..8cfd1c0 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -783,8 +783,11 @@ static void iser_cq_tasklet_fn(unsigned long data)
 unsigned long   xfer_len;
struct iser_conn *ib_conn;
int completed_tx, completed_rx;
+   int ret;
+
completed_tx = completed_rx = 0;
 
+again:
while (ib_poll_cq(cq, 1, wc) == 1) {
desc = (struct iser_rx_desc *) (unsigned long) wc.wr_id;
BUG_ON(desc == NULL);
@@ -807,9 +810,10 @@ static void iser_cq_tasklet_fn(unsigned long data)
if (!(completed_rx  63))
completed_tx += iser_drain_tx_cq(device);
}
-   /* #warning it is assumed here that arming CQ only once its empty *
-*  would not cause interrupts to be missed   */
-   ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
+   ret = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP |
+  IB_CQ_REPORT_MISSED_EVENTS);
+   if (ret  0)
+   goto again;
 
completed_tx += iser_drain_tx_cq(device);
iser_dbg(got %d rx %d tx completions\n, completed_rx, completed_tx);

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/3] IB/core: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-31 Thread Ralph Campbell
The way I understand the sequence of events w/o the
patch is:

ib_req_notify_cq(IB_CQ_NEXT_COMP)
CQE 1 added to queue
callback scheduled via tasklet
future callbacks disarmed
callback function calls ib_req_notify_cq(IB_CQ_NEXT_COMP)
callback function calls ib_poll_cq() and gets CQE 1
callback function calls ib_poll_cq() and gets none
CQE 2 added to queue via IRQ
callback scheduled via tasklet
future callbacks disarmed
callback function returns
some time later, tasklet runs and calls CQ callback function.
callback function calls ib_req_notify_cq(IB_CQ_NEXT_COMP)
callback function calls ib_poll_cq() and gets CQE 2

Since a tasklet or workqueue can be scheduled in the
callback function, the second CQE isn't missed but
there is a scheduling delay before the callback happens
and sees CQE 2.

I guess it is a minor optimization since either CQE 2
will be seen in the first callback while looping in ib_poll_cq()
and then getting a callback later with ib_poll_cq()==0 or
seen in the second callback.

I'm willing to withdraw the 1-3 patches.

I still don't understand why the timing difference matters
to RDS.

On Wed, 2010-03-31 at 11:17 -0700, Roland Dreier wrote:
  ib_req_notify_cq(IB_CQ_NEXT_COMP) is not guaranteed to generate
   a callback for the next completion entered since there is a race
   between arming the callback and another CQE being added to the queue.
   The IB_CQ_REPORT_MISSED_EVENTS flag was added to detect this
   race and allow the verbs consumer to call ib_poll_cq() and
   ib_req_notify_cq() again to avoid delays in processing the CQE.
 
 I'm not sure I understand the race you're fixing here... the existing
 code does the rearm before polling:
 
   +  int ret;

  port_priv = container_of(work, struct ib_mad_port_private, work);
   -  ib_req_notify_cq(port_priv-cq, IB_CQ_NEXT_COMP);

   +again:
  while (ib_poll_cq(port_priv-cq, 1, wc) == 1) {
  if (wc.status == IB_WC_SUCCESS) {
  switch (wc.opcode) {
   @@ -2246,6 +2247,10 @@ static void ib_mad_completion_handler(struct 
 work_struct *work)
  } else
  mad_error_handler(port_priv, wc);
  }
   +  ret = ib_req_notify_cq(port_priv-cq, IB_CQ_NEXT_COMP |
   +IB_CQ_REPORT_MISSED_EVENTS);
   +  if (ret  0)
   +  goto again;
 
 The only issue with the existing code is that it may trigger extra
 events that will find the CQ empty when polling.
 
 So this may be a valid optimization but I don't see it fixing any missed
 events.  Am I missing something?
 
 Also for all these fixes, I think you only want to rearm the CQ once and
 go back and poll if you get a missed events warning; the next time the
 CQ is empty, then you know another event will happen.
 
  - R.


--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] IB/rds: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-30 Thread Ralph Campbell
ib_req_notify_cq(IB_CQ_NEXT_COMP) is not guaranteed to generate
a callback for the next completion entered since there is a race
between arming the callback and another CQE being added to the queue.
OpenFabrics added a IB_CQ_REPORT_MISSED_EVENTS flag to detect this
race and allow the verbs consumer to call ib_poll_cq() and
ib_req_notify_cq() again to avoid delays in processing the CQE.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

This patch by itself should improve RDS performance over QLogic
HCAs.  I was running qperf rds_bw tests and would sometimes
see unexpected opcode 0xdead messages from
rds_ib_send_cq_comp_handler(). I have looked very closely at the
code and I didn't see any race conditions which would explain
why delaying the completion callback would cause the message but
with this patch, I don't see the error message.

 net/rds/ib_send.c |   10 +++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c
index a10fab6..609ae66 100644
--- a/net/rds/ib_send.c
+++ b/net/rds/ib_send.c
@@ -187,10 +187,8 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void 
*context)
 
rdsdebug(cq %p conn %p\n, cq, conn);
rds_ib_stats_inc(s_ib_tx_cq_call);
-   ret = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP);
-   if (ret)
-   rdsdebug(ib_req_notify_cq send failed: %d\n, ret);
 
+again:
while (ib_poll_cq(cq, 1, wc)  0) {
rdsdebug(wc wr_id 0x%llx status %u byte_len %u imm_data %u\n,
 (unsigned long long)wc.wr_id, wc.status, wc.byte_len,
@@ -264,6 +262,12 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void 
*context)
conn-c_faddr, wc.status);
}
}
+   ret = ib_req_notify_cq(cq, IB_CQ_NEXT_COMP |
+  IB_CQ_REPORT_MISSED_EVENTS);
+   if (ret  0)
+   goto again;
+   if (ret  0)
+   rdsdebug(ib_req_notify_cq send failed: %d\n, ret);
 }
 
 /*
-- 
1.6.6.1



--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] IB/rds: use IB_CQ_REPORT_MISSED_EVENTS to avoid missed CQ callbacks

2010-03-30 Thread Ralph Campbell
On Tue, 2010-03-30 at 16:30 -0700, Roland Dreier wrote:
  OpenFabrics added a IB_CQ_REPORT_MISSED_EVENTS flag to detect this
 
 OpenFabrics?  Funny, I thought I added that flag.

You did. I can change the comment if you like.

 (This is not a serious objection ... I'm just being annoying.  Being
 serious, I'm happy to see this used outside of IPoIB and this looks like
 a good optimization)
 
   This patch by itself should improve RDS performance over QLogic HCAs
 
 Out of curiousity have you measured an improvement?

It is a great improvement over a bunch of printks and then
hitting BUG_ON() in __rds_ib_ring_used().

An actual performance difference will have to wait until
the underlying race is better understood. I thought this
patch might spark a discussion since the code in
rds_ib_send_cq_comp_handler() calls printk_ratelimit()
so the 0xdead message must have been seen before enough
to warrant adding the call and the comment:
/* In the error case, wc.opcode sometimes contains garbage */


--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-03-29 Thread Ralph Campbell
On Sun, 2010-03-28 at 09:02 -0700, Eli Cohen wrote:
 On Thu, Mar 04, 2010 at 10:58:27AM -0800, Ralph Campbell wrote:
  Subject: [PATCH v3] IB/ipoib: fix dangling pointer references to 
  ipoib_neigh and ipoib_path
  
  When using connected mode, ipoib_cm_create_tx() kmallocs a
  struct ipoib_cm_tx which contains pointers to ipoib_neigh and
  ipoib_path. If the paths are flushed or the struct neighbour is
  destroyed, the pointers held by struct ipoib_cm_tx can reference
  freed memory.
  
 I could use some more content here as this is quite a large patch.
 Anyway below are some comments. I think besides reviewing this patch
 we need to make sure it has been checked in real life.

Do you mean more details about how ipoib_cm_tx can be used after
being freed or more about how the changes fix the problem?

I have been waiting for our internal regression tests to finish
and to collect review feedback before sending out the final version
of the patch.

  +/*
  + * Search the list of connections to be started and remove any entries
  + * which match the path being destroyed.
  + *
  + * This should be called with netif_tx_lock_bh() and priv-lock held.
  + */
  +void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path)
  +{
  +   struct ipoib_dev_priv *priv = netdev_priv(dev);
  +   struct ipoib_cm_tx *tx;
  +
  +   list_for_each_entry(tx, priv-cm.start_list, list) {
  +   tx = list_entry(priv-cm.start_list.next, typeof(*tx), list);
  +   if (tx-path == path) {
  +   tx-path = NULL;
  +   list_del_init(tx-list);
  +   break;
  +   }
  }
   }
 
 Looks to me like we may find struct ipoib_cm_tx objects hanging and
 not freed. This could happen if they were just added to start_list and
 removed by ipoib_cm_flush_path() before being processed by
 ipoib_cm_tx_start().

Quite right. I should also use list_for_each_entry_safe().
I will fix this.

  -static int __path_add(struct net_device *dev, struct ipoib_path *path)
  +static void __path_add(struct net_device *dev, struct ipoib_path *path)
   {
  struct ipoib_dev_priv *priv = netdev_priv(dev);
  struct rb_node **n = priv-path_tree.rb_node;
  @@ -249,44 +252,26 @@ static int __path_add(struct net_device *dev, struct 
  ipoib_path *path)
  n = pn-rb_left;
  else if (ret  0)
  n = pn-rb_right;
  -   else
  -   return -EEXIST;
  +   else /* Should never happen since we always search first */
  +   return;
  }
 
 Why not remove the last else and change the else if into else?

I don't understand. This is left, right, or return.
I'm only changing the return value to void since it is
never used.

  }
  @@ -460,19 +446,13 @@ static void path_rec_completion(int status,
  memcpy(neigh-dgid.raw, path-pathrec.dgid.raw,
 sizeof(union ib_gid));
   
  -   if (ipoib_cm_enabled(dev, neigh-neighbour)) {
  -   if (!ipoib_cm_get(neigh))
  -   ipoib_cm_set(neigh, 
  ipoib_cm_create_tx(dev,
  -  
  path,
  -  
  neigh));
  -   if (!ipoib_cm_get(neigh)) {
  -   list_del(neigh-list);
  -   if (neigh-ah)
  -   ipoib_put_ah(neigh-ah);
  -   ipoib_neigh_free(dev, neigh);
  -   continue;
  -   }
  -   }
 ipoib_cm_set() is called only once in neigh_alloc(), setting neigh-cm
 to  NULL, and never again so all calls to ipoib_cm_get() will return
 NULL.

ipoib_cm_set() is only called once since I changed
ipoib_cm_create_tx() to initialize neigh-cm and return void.
To me, it is more clear to let ipoib_cm.c do as much of
the CM specific work as possible instead of defining two
versions of a function for when CM is compiled in or not.
I guess I could change neigh_alloc() to call kzmalloc()
and remove ipoib_cm_set().
Normally, I would define set/get pairs but ipoib_main.c
doesn't really need to use the pointer, just know that it
has been allocated and be able to pass it to ipoib_cm.c
I guess we could hide more of the details by just passing
neigh and letting the CM functions get the ipoib_cm_tx pointer.
It is all a matter of style so I'm OK with changing it back
to the original or making it a separate patch (probably wiser).

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [ewg] [PATCH] ipoib: Fix lockup of the tx queue

2010-03-11 Thread Ralph Campbell
On Thu, 2010-03-11 at 13:38 -0800, Roland Dreier wrote:
 good debugging, applied thanks.
 
 I do worry (as Moni mentioned) that this doesn't explain why you would
 get send failures in this case, but the patch itself is well-explained
 and looks obviously correct so I think we should apply it.

Well, after more testing it seems there may still be a problem.
I haven't isolated it yet though. I could definitely use help
reviewing the code changes.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [ewg] [PATCH] ipoib: Fix lockup of the tx queue

2010-03-11 Thread Ralph Campbell
Sorry, I was referring to my patch not Eli's.

On Thu, 2010-03-11 at 13:41 -0800, Ralph Campbell wrote:
 On Thu, 2010-03-11 at 13:38 -0800, Roland Dreier wrote:
  good debugging, applied thanks.
  
  I do worry (as Moni mentioned) that this doesn't explain why you would
  get send failures in this case, but the patch itself is well-explained
  and looks obviously correct so I think we should apply it.
 
 Well, after more testing it seems there may still be a problem.
 I haven't isolated it yet though. I could definitely use help
 reviewing the code changes.
 
 ___
 ewg mailing list
 e...@lists.openfabrics.org
 http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg


--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [ewg] [PATCH] ipoib: Fix lockup of the tx queue

2010-03-11 Thread Ralph Campbell
On Thu, 2010-03-11 at 13:52 -0800, Roland Dreier wrote:
  Sorry, I was referring to my patch not Eli's.
 
 Heh, I never would have said anything about your patch was obvious.
 I skimmed yours once but I do want to read it more carefully.
 
 Did you ever say what test case you are using to provoke the problem you're 
 fixing?

I think I did but it is just UDP stress tests in general.
Throwing in some link failures and switching between connected
and datagram modes helps too. netperf, qperf, etc. should work.
Anything which causes the connected mode QP to fail should
exercise the fix too.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] IB/ipoib: fix dangling pointer references to ipoib_neigh and ipoib_path

2010-03-01 Thread Ralph Campbell
When using connected mode, ipoib_cm_create_tx() kmallocs a
struct ipoib_cm_tx which contains pointers to ipoib_neigh and
ipoib_path. If the paths are flushed or the struct neighbour is
destroyed, the pointers held by struct ipoib_cm_tx can reference
freed memory.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

I was able to remove the kref_t added to struct ipoib_path and ipoib_neigh.
The key is to delete references to ipoib_neigh and ipoib_path
when ipoib_neigh_cleanup() is called.

 drivers/infiniband/ulp/ipoib/ipoib.h   |   24 ++-
 drivers/infiniband/ulp/ipoib/ipoib_cm.c|  105 +-
 drivers/infiniband/ulp/ipoib/ipoib_main.c  |  267 +++-
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |   95 +++--
 4 files changed, 222 insertions(+), 269 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h 
b/drivers/infiniband/ulp/ipoib/ipoib.h
index 753a983..84bb561 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -415,9 +415,7 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct 
neighbour *neigh)
 INFINIBAND_ALEN, sizeof(void *));
 }
 
-struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
- struct net_device *dev);
-void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
+void ipoib_neigh_flush(struct ipoib_neigh *neigh);
 
 extern struct workqueue_struct *ipoib_workqueue;
 
@@ -464,7 +462,8 @@ void ipoib_dev_cleanup(struct net_device *dev);
 
 void ipoib_mcast_join_task(struct work_struct *work);
 void ipoib_mcast_carrier_on_task(struct work_struct *work);
-void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
+void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb,
+ struct ipoib_neigh *neigh);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
 int ipoib_mcast_start_thread(struct net_device *dev);
@@ -567,9 +566,10 @@ void ipoib_cm_dev_stop(struct net_device *dev);
 int ipoib_cm_dev_init(struct net_device *dev);
 int ipoib_cm_add_mode_attr(struct net_device *dev);
 void ipoib_cm_dev_cleanup(struct net_device *dev);
-struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
ipoib_path *path,
-   struct ipoib_neigh *neigh);
+void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
+   struct ipoib_neigh *neigh);
 void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx);
+void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path);
 void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
   unsigned int mtu);
 void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc);
@@ -646,10 +646,10 @@ void ipoib_cm_dev_cleanup(struct net_device *dev)
 }
 
 static inline
-struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct 
ipoib_path *path,
-   struct ipoib_neigh *neigh)
+void ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path *path,
+   struct ipoib_neigh *neigh)
 {
-   return NULL;
+   return;
 }
 
 static inline
@@ -659,6 +659,12 @@ void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx)
 }
 
 static inline
+void ipoib_cm_flush_path(struct net_device *dev, struct ipoib_path *path)
+{
+   return;
+}
+
+static inline
 int ipoib_cm_add_mode_attr(struct net_device *dev)
 {
return 0;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c 
b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 30bdf42..4ec4ebc 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -794,31 +794,14 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct 
ib_wc *wc)
 
if (wc-status != IB_WC_SUCCESS 
wc-status != IB_WC_WR_FLUSH_ERR) {
-   struct ipoib_neigh *neigh;
-
ipoib_dbg(priv, failed cm send event 
   (status=%d, wrid=%d vend_err %x)\n,
   wc-status, wr_id, wc-vendor_err);
 
spin_lock_irqsave(priv-lock, flags);
-   neigh = tx-neigh;
-
-   if (neigh) {
-   neigh-cm = NULL;
-   list_del(neigh-list);
-   if (neigh-ah)
-   ipoib_put_ah(neigh-ah);
-   ipoib_neigh_free(dev, neigh);
-
-   tx-neigh = NULL;
-   }
-
-   if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, tx-flags)) {
-   list_move(tx-list, priv-cm.reap_list);
-   queue_work(ipoib_workqueue, priv-cm.reap_task);
-   }
 
clear_bit(IPOIB_FLAG_OPER_UP, tx-flags);
+   ipoib_cm_destroy_tx(tx);
 
spin_unlock_irqrestore(priv-lock, flags

Re: IPoIB memory use after free

2010-02-18 Thread Ralph Campbell
On Wed, 2010-02-17 at 12:08 -0800, Arthur Kepner wrote:
 On Wed, Feb 17, 2010 at 12:02:36PM -0800, Ralph Campbell wrote:
  I have been tracking down a kernel panic while running qperf udp_bw
  tests and it looks like ib_ipoib is using memory after freeing it.
  
  The problem is with connected mode. I don't see the panic with
  datagram mode. Looking at the source code, I see that the process
  of creating the QP with the connection manager, ipoib_cm_create_tx(),
  has pointers to struct ipoib_neigh and struct ipoib_path but there
  doesn't seem to be a reference count or struct completion similar to
  the way the SA path record look up process has to prevent this.
  
  I'm working on a patch to test this theory but wanted to post
  this before going too far in case others are already aware
  of the problem and working on it.
  
 
 Could what you're seeing be related to what's reported here:
 
 http://lists.openfabrics.org/pipermail/general/2008-April/049629.html

It is related but it is not the same since I'm talking about
struct ipoib_cm_tx holding a stale pointer instead of in
ipoib_neigh_cleanup().

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


IPoIB memory use after free

2010-02-17 Thread Ralph Campbell
I have been tracking down a kernel panic while running qperf udp_bw
tests and it looks like ib_ipoib is using memory after freeing it.

The problem is with connected mode. I don't see the panic with
datagram mode. Looking at the source code, I see that the process
of creating the QP with the connection manager, ipoib_cm_create_tx(),
has pointers to struct ipoib_neigh and struct ipoib_path but there
doesn't seem to be a reference count or struct completion similar to
the way the SA path record look up process has to prevent this.

I'm working on a patch to test this theory but wanted to post
this before going too far in case others are already aware
of the problem and working on it.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] infiniband-diags/ibportstate: allow changes to CA portinfo parameters

2010-01-11 Thread Ralph Campbell
Its been 2 months since I posted this.
What is the current status? Last comment I saw was from Ira
saying either add this functionality to ibportstate or
rename ibportstate but don't split it off into a new command.
My preference is to go with the original patch. I haven't
seen any strong objection to it.

On Thu, 2009-11-05 at 11:56 -0800, Ralph Campbell wrote:
 This patch adds new commands to ibportstate to support initializing
 the link for CAs connected back-to-back. It also allows more than
 one field to be changed at the same time such as lid 23 arm or
 width 1 speed 3 enable.
 
 Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
 ---
 
 diff --git a/infiniband-diags/src/ibportstate.c 
 b/infiniband-diags/src/ibportstate.c
 index e631bfd..192b14e 100644
 --- a/infiniband-diags/src/ibportstate.c
 +++ b/infiniband-diags/src/ibportstate.c
 @@ -46,93 +46,133 @@
 
  #include ibdiag_common.h
 
 +enum port_ops {
 +   QUERY,
 +   ENABLE,
 +   RESET,
 +   DISABLE,
 +   SPEED,
 +   WIDTH,
 +   DOWN,
 +   ARM,
 +   ACTIVE,
 +   VLS,
 +   MTU,
 +   LID,
 +   SMLID,
 +   LMC,
 +};
 +
  struct ibmad_port *srcport;
 +int speed = 15;
 +int width = 255;
 +int lid;
 +int smlid;
 +int lmc;
 +int mtu;
 +int vls;
 +
 +struct {
 +   const char *name;
 +   int *val;
 +   int set;
 +} port_args[] = {
 +   { query, NULL, 0 },   /* QUERY */
 +   { enable, NULL, 0 },  /* ENABLE */
 +   { reset, NULL, 0 },   /* RESET */
 +   { disable, NULL, 0 }, /* DISABLE */
 +   { speed, speed, 0 }, /* SPEED */
 +   { width, width, 0 }, /* WIDTH */
 +   { down, NULL, 0 },/* DOWN */
 +   { arm, NULL, 0 }, /* ARM */
 +   { active, NULL, 0 },  /* ACTIVE */
 +   { vls, vls, 0 }, /* VLS */
 +   { mtu, mtu, 0 }, /* MTU */
 +   { lid, lid, 0 }, /* LID */
 +   { smlid, smlid, 0 }, /* SMLID */
 +   { lmc, lmc, 0 }, /* LMC */
 +};
 +
 +#define NPORT_ARGS (sizeof(port_args) / sizeof(port_args[0]))
 
  /***/
 
 +/*
 + * Return 1 if port is a switch, else zero.
 + */
  static int get_node_info(ib_portid_t * dest, uint8_t * data)
  {
 int node_type;
 
 if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
 -   return -1;
 +   IBERROR(smp query nodeinfo failed);
 
 node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
 if (node_type == IB_NODE_SWITCH)/* Switch NodeType ? */
 -   return 0;
 -   else
 return 1;
 +   else
 +   return 0;
  }
 
 -static int get_port_info(ib_portid_t * dest, uint8_t * data, int portnum,
 -int port_op)
 +static void get_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
 +{
 +   if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, 
 srcport))
 +   IBERROR(smp query portinfo failed);
 +}
 +
 +static void show_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
  {
 char buf[2048];
 char val[64];
 
 -   if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, 
 srcport))
 -   return -1;
 -
 -   if (port_op != 4) {
 -   mad_dump_portstates(buf, sizeof buf, data, sizeof data);
 -   mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, val);
 -   mad_dump_field(IB_PORT_LINK_WIDTH_SUPPORTED_F,
 -  buf + strlen(buf), sizeof buf - strlen(buf),
 -  val);
 -   sprintf(buf + strlen(buf), %s, \n);
 -   mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, val);
 -   mad_dump_field(IB_PORT_LINK_WIDTH_ENABLED_F, buf + 
 strlen(buf),
 -  sizeof buf - strlen(buf), val);
 -   sprintf(buf + strlen(buf), %s, \n);
 -   mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, val);
 -   mad_dump_field(IB_PORT_LINK_WIDTH_ACTIVE_F, buf + strlen(buf),
 -  sizeof buf - strlen(buf), val);
 -   sprintf(buf + strlen(buf), %s, \n);
 -   mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, val);
 -   mad_dump_field(IB_PORT_LINK_SPEED_SUPPORTED_F,
 -  buf + strlen(buf), sizeof buf - strlen(buf),
 -  val);
 -   sprintf(buf + strlen(buf), %s, \n);
 -   mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
 -   mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf + 
 strlen(buf),
 -  sizeof buf - strlen(buf), val);
 -   sprintf(buf + strlen(buf), %s, \n);
 -   mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, val);
 -   mad_dump_field(IB_PORT_LINK_SPEED_ACTIVE_F, buf + strlen(buf),
 -  sizeof buf - strlen(buf), val

Re: InfiniBand/RDMA merge plans for 2.6.33

2009-12-14 Thread Ralph Campbell
On Mon, 2009-12-14 at 10:37 -0800, Roland Dreier wrote:

  - New QLogic qib driver.  Needs at least one more iteration of
cleanups; and I have not had time to look at the latest code in
detail to see exactly what cleanups are needed.  I am concerned
that QLogic chose to abandon the ipath driver as unmaintainable,
and now wants to replace it with an even bigger driver (measured
by lines of code) that does not support the HT device that ipath
supported.  How can we make sure qib has a longer future?

I understand your frustration in having to deal with a large amount
of code. If you included all the Mellanox firmware in the mlx4
driver, it would be huge too. I'm limited in what I can do given
the complexity of the IBTA spec.

QLogic is not abandoning the ipath driver as unmaintainable.
The thought was that trying to incrementally patch in all the changes
needed to support dual ports, QDR, chip register addresses, etc.
would result in larger patches than renaming the driver. It was a
chicken-and-egg problem because until the new code was fully
written and debugged, we couldn't post it and we couldn't patch
ipath until we knew all the places that needed to be changed.

We had a pretty strong business requirement to get support for 
our QDR product into OFED 1.5 and the IB interrop tests required
we get something into OFED. The chip schedule just didn't leave time
to debug everything, get it reviewed and then merge with OFED.
Also, I was out for 5 weeks and that delayed the submission to
linux-rdma.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 0/51] updated patches for adding QIB driver

2009-12-09 Thread Ralph Campbell
OK.
Done.

On Wed, 2009-12-09 at 14:47 -0800, Roland Dreier wrote:
 have not had a chance to look at the new submission yet but I think you
 need at least the following rolled in, to avoid calling __exit code that
 might have been thrown away from the error path of your init function.
 
 Building with CONFIG_DEBUG_SECTION_MISMATCH=y when you see that the
 kernel build tells you that you introduced new section mismatches is
 probably a good idea.
 
 diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c 
 b/drivers/infiniband/hw/qib/qib_file_ops.c
 index 781c87f..53c314f 100644
 --- a/drivers/infiniband/hw/qib/qib_file_ops.c
 +++ b/drivers/infiniband/hw/qib/qib_file_ops.c
 @@ -2450,7 +2450,7 @@ done:
   return ret;
  }
  
 -void __exit qib_dev_cleanup(void)
 +void qib_dev_cleanup(void)
  {
   if (qib_class) {
   class_destroy(qib_class);

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/51] updated patches for adding QIB driver

2009-12-03 Thread Ralph Campbell
The following emails are in response to Rolands comments.
Since the patches are for whole files, its hard to see what
has changed but I describe it below.

A reminder that these depend on the patch I sent earlier which
introduces ib_sysfs_create_port_files() into the ib_core.

---

Changed the Makefile line-by-line to multi-line list of .o files and
removed the -D flags.

Removed qib_trace.[ch]. Debug messages use printk similar to ib_ipath.

Fixed compiles when CONFIG_PCI_MSI is not defined.

Removed #ifdefs and backport code for AER.

Reduced the size of the chip register definition files.

Changed global function names which conflict with ib_ipath to
be prefixed with qib_ (requires ib_ipath and ib_qib to be compiled
into the kernel instead of as separate modules).
--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 01/51] IB/qib: Add Kconfig

2009-12-03 Thread Ralph Campbell
This creates the Kconfig file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/Kconfig |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/Kconfig

diff --git a/drivers/infiniband/hw/qib/Kconfig 
b/drivers/infiniband/hw/qib/Kconfig
new file mode 100644
index 000..1acfb54
--- /dev/null
+++ b/drivers/infiniband/hw/qib/Kconfig
@@ -0,0 +1,11 @@
+config INFINIBAND_QIB
+   tristate QLogic PCIe HCA support
+   depends on 64BIT  NET
+   ---help---
+   This is a driver for QLogic PCIe QLE IB host channel adapters,
+   including InfiniBand verbs support.  This driver allows these
+   devices to be used with both kernel upper level protocols such
+   as IP-over-InfiniBand as well as with userspace applications
+   (in conjunction with InfiniBand userspace access).
+   This driver does not support the QLogic HyperTransport card
+   (model QHT7140).

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 02/51] IB/qib: Add Makefile

2009-12-03 Thread Ralph Campbell
This creates the Makefile file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/Makefile |   15 +++
 1 files changed, 15 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/Makefile

diff --git a/drivers/infiniband/hw/qib/Makefile 
b/drivers/infiniband/hw/qib/Makefile
new file mode 100644
index 000..c6515a1
--- /dev/null
+++ b/drivers/infiniband/hw/qib/Makefile
@@ -0,0 +1,15 @@
+obj-$(CONFIG_INFINIBAND_QIB) += ib_qib.o
+
+ib_qib-y := qib_cq.o qib_diag.o qib_dma.o qib_driver.o qib_eeprom.o \
+   qib_file_ops.o qib_fs.o qib_init.o qib_intr.o qib_keys.o \
+   qib_mad.o qib_mmap.o qib_mr.o qib_pcie.o qib_pio_copy.o \
+   qib_qp.o qib_qsfp.o qib_rc.o qib_ruc.o qib_sdma.o qib_srq.o \
+   qib_sysfs.o qib_twsi.o qib_tx.o qib_uc.o qib_ud.o \
+   qib_user_pages.o qib_user_sdma.o qib_verbs_mcast.o qib_iba7220.o \
+   qib_sd7220.o qib_sd7220_img.o qib_iba7322.o qib_verbs.o
+
+# 6120 has no fallback if no MSI interrupts, others can do INTx
+ib_qib-$(CONFIG_PCI_MSI) += qib_iba6120.o
+
+ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o
+ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 04/51] IB/qib: Add qib_6120_regs.h

2009-12-03 Thread Ralph Campbell
This creates the qib_6120_regs.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_6120_regs.h |  977 +
 1 files changed, 977 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_6120_regs.h

diff --git a/drivers/infiniband/hw/qib/qib_6120_regs.h 
b/drivers/infiniband/hw/qib/qib_6120_regs.h
new file mode 100644
index 000..8108b89
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_6120_regs.h
@@ -0,0 +1,977 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. 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.
+ */
+
+/* This file is mechanically generated from RTL. Any hand-edits will be lost! 
*/
+
+#define QIB_6120_Revision_OFFS 0x0
+#define QIB_6120_Revision_R_Simulator_LSB 0x3F
+#define QIB_6120_Revision_R_Simulator_RMASK 0x1
+#define QIB_6120_Revision_Reserved_LSB 0x28
+#define QIB_6120_Revision_Reserved_RMASK 0x7F
+#define QIB_6120_Revision_BoardID_LSB 0x20
+#define QIB_6120_Revision_BoardID_RMASK 0xFF
+#define QIB_6120_Revision_R_SW_LSB 0x18
+#define QIB_6120_Revision_R_SW_RMASK 0xFF
+#define QIB_6120_Revision_R_Arch_LSB 0x10
+#define QIB_6120_Revision_R_Arch_RMASK 0xFF
+#define QIB_6120_Revision_R_ChipRevMajor_LSB 0x8
+#define QIB_6120_Revision_R_ChipRevMajor_RMASK 0xFF
+#define QIB_6120_Revision_R_ChipRevMinor_LSB 0x0
+#define QIB_6120_Revision_R_ChipRevMinor_RMASK 0xFF
+
+#define QIB_6120_Control_OFFS 0x8
+#define QIB_6120_Control_TxLatency_LSB 0x4
+#define QIB_6120_Control_TxLatency_RMASK 0x1
+#define QIB_6120_Control_PCIERetryBufDiagEn_LSB 0x3
+#define QIB_6120_Control_PCIERetryBufDiagEn_RMASK 0x1
+#define QIB_6120_Control_LinkEn_LSB 0x2
+#define QIB_6120_Control_LinkEn_RMASK 0x1
+#define QIB_6120_Control_FreezeMode_LSB 0x1
+#define QIB_6120_Control_FreezeMode_RMASK 0x1
+#define QIB_6120_Control_SyncReset_LSB 0x0
+#define QIB_6120_Control_SyncReset_RMASK 0x1
+
+#define QIB_6120_PageAlign_OFFS 0x10
+
+#define QIB_6120_PortCnt_OFFS 0x18
+
+#define QIB_6120_SendRegBase_OFFS 0x30
+
+#define QIB_6120_UserRegBase_OFFS 0x38
+
+#define QIB_6120_CntrRegBase_OFFS 0x40
+
+#define QIB_6120_Scratch_OFFS 0x48
+#define QIB_6120_Scratch_TopHalf_LSB 0x20
+#define QIB_6120_Scratch_TopHalf_RMASK 0x
+#define QIB_6120_Scratch_BottomHalf_LSB 0x0
+#define QIB_6120_Scratch_BottomHalf_RMASK 0x
+
+#define QIB_6120_IntBlocked_OFFS 0x60
+#define QIB_6120_IntBlocked_ErrorIntBlocked_LSB 0x1F
+#define QIB_6120_IntBlocked_ErrorIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_PioSetIntBlocked_LSB 0x1E
+#define QIB_6120_IntBlocked_PioSetIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_PioBufAvailIntBlocked_LSB 0x1D
+#define QIB_6120_IntBlocked_PioBufAvailIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_assertGPIOIntBlocked_LSB 0x1C
+#define QIB_6120_IntBlocked_assertGPIOIntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_Reserved_LSB 0xF
+#define QIB_6120_IntBlocked_Reserved_RMASK 0x1FFF
+#define QIB_6120_IntBlocked_RcvAvail4IntBlocked_LSB 0x10
+#define QIB_6120_IntBlocked_RcvAvail4IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail3IntBlocked_LSB 0xF
+#define QIB_6120_IntBlocked_RcvAvail3IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail2IntBlocked_LSB 0xE
+#define QIB_6120_IntBlocked_RcvAvail2IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail1IntBlocked_LSB 0xD
+#define QIB_6120_IntBlocked_RcvAvail1IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_RcvAvail0IntBlocked_LSB 0xC
+#define QIB_6120_IntBlocked_RcvAvail0IntBlocked_RMASK 0x1
+#define QIB_6120_IntBlocked_Reserved1_LSB 0x5
+#define QIB_6120_IntBlocked_Reserved1_RMASK 0x7F
+#define

[PATCH v2 05/51] IB/qib: Add qib_7220.h

2009-12-03 Thread Ralph Campbell
creates the qib_7220.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_7220.h |  158 ++
 1 files changed, 158 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_7220.h

diff --git a/drivers/infiniband/hw/qib/qib_7220.h 
b/drivers/infiniband/hw/qib/qib_7220.h
new file mode 100644
index 000..a68230e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_7220.h
@@ -0,0 +1,158 @@
+#ifndef _QIB_7220_H
+#define _QIB_7220_H
+/*
+ * Copyright (c) 2007, 2009 QLogic Corporation. 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.
+ */
+
+/* grab register-defs auto-generated by HW */
+#include qib_7220_regs.h
+
+/* The number of eager receive TIDs for context zero. */
+#define IBA7220_KRCVEGRCNT  2048U
+
+#define IB_7220_LT_STATE_CFGRCVFCFG  0x09
+#define IB_7220_LT_STATE_CFGWAITRMT  0x0a
+#define IB_7220_LT_STATE_TXREVLANES  0x0d
+#define IB_7220_LT_STATE_CFGENH  0x10
+
+struct qib_chip_specific {
+   u64 __iomem *cregbase;
+   u64 *cntrs;
+   u64 *portcntrs;
+   spinlock_t sdepb_lock; /* serdes EPB bus */
+   spinlock_t rcvmod_lock; /* protect rcvctrl shadow changes */
+   spinlock_t gpio_lock; /* RMW of shadows/regs for ExtCtrl and GPIO */
+   u64 hwerrmask;
+   u64 errormask;
+   u64 gpio_out; /* shadow of kr_gpio_out, for rmw ops */
+   u64 gpio_mask; /* shadow the gpio mask register */
+   u64 extctrl; /* shadow the gpio output enable, etc... */
+   u32 ncntrs;
+   u32 nportcntrs;
+   u32 cntrnamelen;
+   u32 portcntrnamelen;
+   u32 numctxts;
+   u32 rcvegrcnt;
+   u32 autoneg_tries;
+   u32 serdes_first_init_done;
+   u32 sdmabufcnt;
+   u32 lastbuf_for_pio;
+   u32 updthresh; /* current AvailUpdThld */
+   u32 updthresh_dflt; /* default AvailUpdThld */
+   int irq;
+   u8 presets_needed;
+   char emsgbuf[128];
+   char sdmamsgbuf[192];
+   char bitsmsgbuf[64];
+   struct qib_relock {
+   atomic_t relock_timer_active;
+   struct timer_list relock_timer;
+   unsigned int relock_interval; /* in jiffies */
+   } relock_st;
+};
+
+struct qib_chippport_specific {
+   struct qib_pportdata pportdata;
+   wait_queue_head_t autoneg_wait;
+   struct delayed_work autoneg_work;
+   struct timer_list chase_timer;
+   /*
+* these 5 fields are used to establish deltas for IB symbol
+* errors and linkrecovery errors.  They can be reported on
+* some chips during link negotiation prior to INIT, and with
+* DDR when faking DDR negotiations with non-IBTA switches.
+* The chip counters are adjusted at driver unload if there is
+* a non-zero delta.
+*/
+   u64 ibdeltainprog;
+   u64 ibsymdelta;
+   u64 ibsymsnap;
+   u64 iblnkerrdelta;
+   u64 iblnkerrsnap;
+   u64 ibcctrl; /* kr_ibcctrl shadow */
+   u64 ibcddrctrl; /* kr_ibcddrctrl shadow */
+   u64 chase_end;
+   u32 last_delay_mult;
+};
+
+/*
+ * This header file provides the declarations and common definitions
+ * for (mostly) manipulation of the SerDes blocks within the IBA7220.
+ * the functions declared should only be called from within other
+ * 7220-related files such as qib_iba7220.c or qib_sd7220.c.
+ */
+int qib_sd7220_presets(struct qib_devdata *dd);
+int qib_sd7220_init(struct qib_devdata *dd);
+int qib_sd7220_prog_ld(struct qib_devdata *dd, int sdnum, u8 *img,
+  int len, int offset);
+int qib_sd7220_prog_vfy(struct

[PATCH v2 08/51] IB/qib: Add qib_common.h

2009-12-03 Thread Ralph Campbell
creates the qib_common.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_common.h |  755 
 1 files changed, 755 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_common.h

diff --git a/drivers/infiniband/hw/qib/qib_common.h 
b/drivers/infiniband/hw/qib/qib_common.h
new file mode 100644
index 000..51239aa
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_common.h
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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.
+ */
+
+#ifndef _QIB_COMMON_H
+#define _QIB_COMMON_H
+
+/*
+ * This file contains defines, structures, etc. that are used
+ * to communicate between kernel and user code.
+ */
+
+/* This is the IEEE-assigned OUI for QLogic Inc. QLogic_IB */
+#define QIB_SRC_OUI_1 0x00
+#define QIB_SRC_OUI_2 0x11
+#define QIB_SRC_OUI_3 0x75
+
+/* version of protocol header (known to chip also). In the long run,
+ * we should be able to generate and accept a range of version numbers;
+ * for now we only accept one, and it's compiled in.
+ */
+#define IPS_PROTO_VERSION 2
+
+/*
+ * These are compile time constants that you may want to enable or disable
+ * if you are trying to debug problems with code or performance.
+ * QIB_VERBOSE_TRACING define as 1 if you want additional tracing in
+ * fastpath code
+ * QIB_TRACE_REGWRITES define as 1 if you want register writes to be
+ * traced in faspath code
+ * _QIB_TRACING define as 0 if you want to remove all tracing in a
+ * compilation unit
+ * _QIB_DEBUGGING define as 0 if you want to remove debug prints
+ */
+
+/*
+ * The value in the BTH QP field that QLogic_IB uses to differentiate
+ * an qlogic_ib protocol IB packet vs standard IB transport
+ * This it needs to be even (0x656b78), because the LSB is sometimes
+ * used for the MSB of context. The change may cause a problem
+ * interoperating with older software.
+ */
+#define QIB_KD_QP 0x656b78
+
+/*
+ * These are the status bits readable (in ascii form, 64bit value)
+ * from the status sysfs file.  For binary compatibility, values
+ * must remain as is; removed states can be reused for different
+ * purposes.
+ */
+#define QIB_STATUS_INITTED   0x1/* basic initialization done */
+/* Chip has been found and initted */
+#define QIB_STATUS_CHIP_PRESENT 0x20
+/* IB link is at ACTIVE, usable for data traffic */
+#define QIB_STATUS_IB_READY 0x40
+/* link is configured, LID, MTU, etc. have been set */
+#define QIB_STATUS_IB_CONF  0x80
+/* A Fatal hardware error has occurred. */
+#define QIB_STATUS_HWERROR 0x200
+
+/*
+ * The list of usermode accessible registers.  Also see Reg_* later in file.
+ */
+enum qib_ureg {
+   /* (RO)  DMA RcvHdr to be used next. */
+   ur_rcvhdrtail = 0,
+   /* (RW)  RcvHdr entry to be processed next by host. */
+   ur_rcvhdrhead = 1,
+   /* (RO)  Index of next Eager index to use. */
+   ur_rcvegrindextail = 2,
+   /* (RW)  Eager TID to be processed next */
+   ur_rcvegrindexhead = 3,
+   /* For internal use only; max register number. */
+   _QIB_UregMax
+};
+
+/* bit values for spi_runtime_flags */
+#define QIB_RUNTIME_PCIE0x0002
+#define QIB_RUNTIME_FORCE_WC_ORDER  0x0004
+#define QIB_RUNTIME_RCVHDR_COPY 0x0008
+#define QIB_RUNTIME_MASTER  0x0010
+#define QIB_RUNTIME_NODMA_RTAIL 0x0080
+#define QIB_RUNTIME_SPECIAL_TRIGGER 0x0100
+#define QIB_RUNTIME_SDMA0x0200
+#define

[PATCH v2 10/51] IB/qib: Add qib_debug.h

2009-12-03 Thread Ralph Campbell
creates the qib_debug.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_debug.h |   85 +
 1 files changed, 85 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_debug.h

diff --git a/drivers/infiniband/hw/qib/qib_debug.h 
b/drivers/infiniband/hw/qib/qib_debug.h
new file mode 100644
index 000..e6a77cd
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_debug.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2006, 2007, 2009 QLogic Corporation. All rights reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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.
+ */
+
+#ifndef _QIB_DEBUG_H
+#define _QIB_DEBUG_H
+
+#ifndef _QIB_DEBUGGING  /* debugging enabled or not */
+#define _QIB_DEBUGGING 1
+#endif
+
+#if _QIB_DEBUGGING
+
+/*
+ * Mask values for debugging.  The scheme allows us to compile out any
+ * of the debug tracing stuff, and if compiled in, to enable or disable
+ * dynamically.  This can be set at modprobe time also:
+ *  modprobe qlogic_ib.ko qlogic_ib_debug=7
+ */
+
+#define __QIB_INFO0x1   /* logging of dev_info and dev_err */
+#define __QIB_DBG 0x2   /* generic debug */
+/* leave some low verbosity spots open */
+#define __QIB_RVPKTDBG0x10  /* verbose pktrcv debug */
+#define __QIB_INITDBG 0x20  /* init-level debug */
+#define __QIB_VERBDBG 0x40  /* very verbose debug */
+#define __QIB_PKTDBG  0x80  /* print packet data */
+#define __QIB_PROCDBG 0x100 /* process init/exit debug */
+#define __QIB_MMDBG   0x200 /* mmap, etc debug */
+#define __QIB_ERRPKTDBG   0x400 /* packet error debugging */
+#define __QIB_SDMADBG 0x800 /* Send DMA */
+#define __QIB_VPKTDBG 0x1000 /* Dump IB contents being copied to send buf 
*/
+#define __QIB_LINKVERBDBG 0x20  /* very verbose linkchange debug */
+
+#else   /* _QIB_DEBUGGING */
+
+/*
+ * define all of these even with debugging off, for the few places that do
+ * if(qlogic_ib_debug  _QIB_xyzzy), but in a way that will make the
+ * compiler eliminate the code
+ */
+
+#define __QIB_DBG   0x0 /* generic debug */
+#define __QIB_VERBDBG   0x0 /* very verbose debug */
+#define __QIB_PKTDBG0x0 /* print packet data */
+#define __QIB_PROCDBG   0x0  /* process init/exit debug */
+#define __QIB_MMDBG 0x0 /* mmap, etc debug */
+#define __QIB_ERRPKTDBG 0x0 /* packet error debugging */
+#define __QIB_SDMADBG   0x0 /* Send DMA */
+#define __QIB_LINKVERBDBG 0x0   /* very verbose linkchange debug */
+
+#endif  /* _QIB_DEBUGGING */
+
+#define __QIB_VERBOSEDBG __QIB_VERBDBG
+
+#endif  /* _QIB_DEBUG_H */

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 11/51] IB/qib: Add qib_diag.c

2009-12-03 Thread Ralph Campbell
creates the qib_diag.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_diag.c |  908 ++
 1 files changed, 908 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_diag.c

diff --git a/drivers/infiniband/hw/qib/qib_diag.c 
b/drivers/infiniband/hw/qib/qib_diag.c
new file mode 100644
index 000..f5cb4cc
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_diag.c
@@ -0,0 +1,908 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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.
+ */
+
+/*
+ * This file contains support for diagnostic functions.  It is accessed by
+ * opening the qib_diag device, normally minor number 129.  Diagnostic use
+ * of the QLogic_IB chip may render the chip or board unusable until the
+ * driver is unloaded, or in some cases, until the system is rebooted.
+ *
+ * Accesses to the chip through this interface are not similar to going
+ * through the /sys/bus/pci resource mmap interface.
+ */
+
+#include linux/io.h
+#include linux/pci.h
+#include linux/poll.h
+#include linux/vmalloc.h
+#include linux/fs.h
+#include linux/uaccess.h
+
+#include qib.h
+#include qib_common.h
+
+/*
+ * Each client that opens the diag device must read then write
+ * offset 0, to prevent lossage from random cat or od. diag_state
+ * sequences this handshake.
+ */
+enum diag_state { UNUSED = 0, OPENED, INIT, READY };
+
+/* State for an individual client. PID so children cannot abuse handshake */
+static struct qib_diag_client {
+   struct qib_diag_client *next;
+   struct qib_devdata *dd;
+   pid_t pid;
+   enum diag_state state;
+} *client_pool;
+
+/*
+ * Get a client struct. Recycled if possible, else kmalloc.
+ * Must be called with qib_mutex held
+ */
+static struct qib_diag_client *get_client(struct qib_devdata *dd)
+{
+   struct qib_diag_client *dc;
+
+   dc = client_pool;
+   if (dc)
+   /* got from pool remove it and use */
+   client_pool = dc-next;
+   else
+   /* None in pool, alloc and init */
+   dc = kmalloc(sizeof *dc, GFP_KERNEL);
+
+   if (dc) {
+   dc-next = NULL;
+   dc-dd = dd;
+   dc-pid = current-pid;
+   dc-state = OPENED;
+   }
+   return dc;
+}
+
+/*
+ * Return to pool. Must be called with qib_mutex held
+ */
+static void return_client(struct qib_diag_client *dc)
+{
+   struct qib_devdata *dd = dc-dd;
+   struct qib_diag_client *tdc, *rdc;
+
+   rdc = NULL;
+   if (dc == dd-diag_client) {
+   dd-diag_client = dc-next;
+   rdc = dc;
+   } else {
+   tdc = dc-dd-diag_client;
+   while (tdc) {
+   if (dc == tdc-next) {
+   tdc-next = dc-next;
+   rdc = dc;
+   break;
+   }
+   tdc = tdc-next;
+   }
+   }
+   if (rdc) {
+   rdc-state = UNUSED;
+   rdc-dd = NULL;
+   rdc-pid = 0;
+   rdc-next = client_pool;
+   client_pool = rdc;
+   }
+}
+
+static int qib_diag_open(struct inode *in, struct file *fp);
+static int qib_diag_release(struct inode *in, struct file *fp);
+static ssize_t qib_diag_read(struct file *fp, char __user *data,
+size_t count, loff_t *off);
+static ssize_t qib_diag_write(struct file *fp

[PATCH v2 12/51] IB/qib: Add qib_dma.c

2009-12-03 Thread Ralph Campbell
creates the qib_dma.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_dma.c |  182 +++
 1 files changed, 182 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_dma.c

diff --git a/drivers/infiniband/hw/qib/qib_dma.c 
b/drivers/infiniband/hw/qib/qib_dma.c
new file mode 100644
index 000..f84085e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_dma.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2006, 2009 QLogic, Corporation. 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/types.h
+#include linux/scatterlist.h
+
+#include qib_verbs.h
+
+#define BAD_DMA_ADDRESS ((u64) 0)
+
+/*
+ * The following functions implement driver specific replacements
+ * for the ib_dma_*() functions.
+ *
+ * These functions return kernel virtual addresses instead of
+ * device bus addresses since the driver uses the CPU to copy
+ * data instead of using hardware DMA.
+ */
+
+static int qib_mapping_error(struct ib_device *dev, u64 dma_addr)
+{
+   return dma_addr == BAD_DMA_ADDRESS;
+}
+
+static u64 qib_dma_map_single(struct ib_device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+   return (u64) cpu_addr;
+}
+
+static void qib_dma_unmap_single(struct ib_device *dev, u64 addr, size_t size,
+enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+}
+
+static u64 qib_dma_map_page(struct ib_device *dev, struct page *page,
+   unsigned long offset, size_t size,
+   enum dma_data_direction direction)
+{
+   u64 addr;
+
+   BUG_ON(!valid_dma_direction(direction));
+
+   if (offset + size  PAGE_SIZE) {
+   addr = BAD_DMA_ADDRESS;
+   goto done;
+   }
+
+   addr = (u64) page_address(page);
+   if (addr)
+   addr += offset;
+   /* TODO: handle highmem pages */
+
+done:
+   return addr;
+}
+
+static void qib_dma_unmap_page(struct ib_device *dev, u64 addr, size_t size,
+  enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+}
+
+static int qib_map_sg(struct ib_device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction direction)
+{
+   struct scatterlist *sg;
+   u64 addr;
+   int i;
+   int ret = nents;
+
+   BUG_ON(!valid_dma_direction(direction));
+
+   for_each_sg(sgl, sg, nents, i) {
+   addr = (u64) page_address(sg_page(sg));
+   /* TODO: handle highmem pages */
+   if (!addr) {
+   ret = 0;
+   break;
+   }
+   }
+   return ret;
+}
+
+static void qib_unmap_sg(struct ib_device *dev,
+struct scatterlist *sg, int nents,
+enum dma_data_direction direction)
+{
+   BUG_ON(!valid_dma_direction(direction));
+}
+
+static u64 qib_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
+{
+   u64 addr = (u64) page_address(sg_page(sg));
+
+   if (addr)
+   addr += sg-offset;
+   return addr;
+}
+
+static unsigned int qib_sg_dma_len(struct ib_device *dev,
+  struct scatterlist *sg)
+{
+   return sg-length;
+}
+
+static void qib_sync_single_for_cpu(struct ib_device *dev, u64 addr,
+   size_t size, enum dma_data_direction dir

[PATCH v2 14/51] IB/qib: Add qib_eeprom.c

2009-12-03 Thread Ralph Campbell
creates the qib_eeprom.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_eeprom.c |  460 
 1 files changed, 460 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_eeprom.c

diff --git a/drivers/infiniband/hw/qib/qib_eeprom.c 
b/drivers/infiniband/hw/qib/qib_eeprom.c
new file mode 100644
index 000..7a6fe41
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_eeprom.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/delay.h
+#include linux/pci.h
+#include linux/vmalloc.h
+
+#include qib.h
+
+/*
+ * Functions specific to the serial EEPROM on cards handled by ib_qib.
+ * The actual serail interface code is in qib_twsi.c. This file is a client
+ */
+
+/**
+ * qib_eeprom_read - receives bytes from the eeprom via I2C
+ * @dd: the qlogic_ib device
+ * @eeprom_offset: address to read from
+ * @buffer: where to store result
+ * @len: number of bytes to receive
+ */
+int qib_eeprom_read(struct qib_devdata *dd, u8 eeprom_offset,
+   void *buff, int len)
+{
+   int ret;
+
+   ret = mutex_lock_interruptible(dd-eep_lock);
+   if (!ret) {
+   ret = qib_twsi_reset(dd);
+   if (ret)
+   qib_dev_err(dd, TWSI Reset failed, EEPROM Rd\n);
+   else
+   ret = qib_twsi_blk_rd(dd, dd-twsi_eeprom_dev,
+ eeprom_offset, buff, len);
+   mutex_unlock(dd-eep_lock);
+   }
+
+   return ret;
+}
+
+/*
+ * Actually update the eeprom, first doing write enable if
+ * needed, then restoring write enable state.
+ * Must be called with eep_lock held
+ */
+static int eeprom_write_with_enable(struct qib_devdata *dd, u8 offset,
+const void *buf, int len)
+{
+   int ret, pwen;
+
+   pwen = dd-f_eeprom_wen(dd, 1);
+   ret = qib_twsi_reset(dd);
+   if (ret)
+   qib_dev_err(dd, TWSI Reset failed, EEPROM Wr\n);
+   else
+   ret = qib_twsi_blk_wr(dd, dd-twsi_eeprom_dev,
+ offset, buf, len);
+   dd-f_eeprom_wen(dd, pwen);
+   return ret;
+}
+
+/**
+ * qib_eeprom_write - writes data to the eeprom via I2C
+ * @dd: the qlogic_ib device
+ * @eeprom_offset: where to place data
+ * @buffer: data to write
+ * @len: number of bytes to write
+ */
+int qib_eeprom_write(struct qib_devdata *dd, u8 eeprom_offset,
+const void *buff, int len)
+{
+   int ret;
+
+   ret = mutex_lock_interruptible(dd-eep_lock);
+   if (!ret) {
+   ret = eeprom_write_with_enable(dd, eeprom_offset, buff, len);
+   mutex_unlock(dd-eep_lock);
+   }
+
+   return ret;
+}
+
+static u8 flash_csum(struct qib_flash *ifp, int adjust)
+{
+   u8 *ip = (u8 *) ifp;
+   u8 csum = 0, len;
+
+   /*
+* Limit length checksummed to max length of actual data.
+* Checksum of erased eeprom will still be bad, but we avoid
+* reading past the end of the buffer we were passed.
+*/
+   len = ifp-if_length;
+   if (len  sizeof(struct qib_flash))
+   len = sizeof(struct qib_flash);
+   while (len--)
+   csum += *ip++;
+   csum -= ifp-if_csum;
+   csum = ~csum;
+   if (adjust)
+   ifp-if_csum = csum;
+
+   return csum;
+}
+
+/**
+ * qib_get_eeprom_info- get

[PATCH v2 20/51] IB/qib: Add qib_init.c

2009-12-03 Thread Ralph Campbell
creates the qib_init.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_init.c | 1618 ++
 1 files changed, 1618 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_init.c

diff --git a/drivers/infiniband/hw/qib/qib_init.c 
b/drivers/infiniband/hw/qib/qib_init.c
new file mode 100644
index 000..6ce1128
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -0,0 +1,1618 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/pci.h
+#include linux/netdevice.h
+#include linux/vmalloc.h
+#include linux/delay.h
+#include linux/idr.h
+
+#include qib.h
+#include qib_common.h
+
+/*
+ * min buffers we want to have per context, after driver
+ */
+#define QIB_MIN_USER_CTXT_BUFCNT 7
+
+#define QLOGIC_IB_R_SOFTWARE_MASK 0xFF
+#define QLOGIC_IB_R_SOFTWARE_SHIFT 24
+#define QLOGIC_IB_R_EMULATOR_MASK (1ULL62)
+
+/*
+ * Number of ctxts we are configured to use (to allow for more pio
+ * buffers per ctxt, etc.)  Zero means use chip value.
+ */
+ushort qib_cfgctxts;
+module_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO);
+MODULE_PARM_DESC(cfgctxts, Set max number of contexts to use);
+
+/*
+ * If set, do not write to any regs if avoidable, hack to allow
+ * check for deranged default register values.
+ */
+ushort qib_mini_init;
+module_param_named(mini_init, qib_mini_init, ushort, S_IRUGO);
+MODULE_PARM_DESC(mini_init, If set, do minimal diag init);
+
+unsigned qib_n_krcv_queues;
+module_param_named(krcvqs, qib_n_krcv_queues, uint, S_IRUGO);
+MODULE_PARM_DESC(krcvqs, number of kernel receive queues per IB port);
+
+/*
+ * qib_wc_pat parameter:
+ *  0 is WC via MTRR
+ *  1 is WC via PAT
+ *  If PAT initialization fails, code reverts back to MTRR
+ */
+unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */
+module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO);
+MODULE_PARM_DESC(wc_pat, enable write-combining via PAT mechanism);
+
+static void verify_interrupt(unsigned long);
+
+static struct idr qib_unit_table;
+
+/* set number of contexts we'll actually use */
+void qib_set_ctxtcnt(struct qib_devdata *dd)
+{
+   if (!qib_cfgctxts)
+   dd-cfgctxts = dd-ctxtcnt;
+   else if (qib_cfgctxts  dd-num_pports) {
+   dd-cfgctxts = dd-ctxtcnt;
+   qib_dbg(Configured to use too few ctxts (%u); using %u\n,
+   qib_cfgctxts, dd-cfgctxts);
+   } else if (qib_cfgctxts = dd-ctxtcnt) {
+   dd-cfgctxts = qib_cfgctxts;
+   qib_cdbg(INIT, Configured to use %u ctxts\n, dd-cfgctxts);
+   } else {
+   dd-cfgctxts = dd-ctxtcnt;
+   qib_dbg(Configured to use too many ctxts (%u); using %u\n,
+   qib_cfgctxts, dd-cfgctxts);
+   }
+}
+
+/*
+ * Common code for creating the receive context array.
+ */
+int qib_create_ctxts(struct qib_devdata *dd)
+{
+   unsigned i;
+   int ret;
+
+   /*
+* Allocate full ctxtcnt array, rather than just cfgctxts, because
+* cleanup iterates across all possible ctxts.
+*/
+   dd-rcd = kzalloc(sizeof(*dd-rcd) * dd-ctxtcnt, GFP_KERNEL);
+   if (!dd-rcd) {
+   qib_dev_err(dd, Unable to allocate ctxtdata array, 
+   failing\n);
+   ret = -ENOMEM;
+   goto done;
+   }
+
+   /* create (one or more) kctxt */
+   for (i = 0; i  dd

[PATCH v2 21/51] IB/qib: Add qib_intr.c

2009-12-03 Thread Ralph Campbell
creates the qib_intr.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_intr.c |  217 ++
 1 files changed, 217 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_intr.c

diff --git a/drivers/infiniband/hw/qib/qib_intr.c 
b/drivers/infiniband/hw/qib/qib_intr.c
new file mode 100644
index 000..46e128a
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_intr.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/pci.h
+#include linux/delay.h
+
+#include qib.h
+#include qib_common.h
+
+/**
+ * qib_format_hwmsg - format a single hwerror message
+ * @msg message buffer
+ * @msgl length of message buffer
+ * @hwmsg message to add to message buffer
+ */
+static void qib_format_hwmsg(char *msg, size_t msgl, const char *hwmsg)
+{
+   strlcat(msg, [, msgl);
+   strlcat(msg, hwmsg, msgl);
+   strlcat(msg, ], msgl);
+}
+
+/**
+ * qib_format_hwerrors - format hardware error messages for display
+ * @hwerrs hardware errors bit vector
+ * @hwerrmsgs hardware error descriptions
+ * @nhwerrmsgs number of hwerrmsgs
+ * @msg message buffer
+ * @msgl message buffer length
+ */
+void qib_format_hwerrors(u64 hwerrs, const struct qib_hwerror_msgs *hwerrmsgs,
+size_t nhwerrmsgs, char *msg, size_t msgl)
+{
+   int i;
+
+   for (i = 0; i  nhwerrmsgs; i++)
+   if (hwerrs  hwerrmsgs[i].mask)
+   qib_format_hwmsg(msg, msgl, hwerrmsgs[i].msg);
+}
+
+static void signal_ib_event(struct qib_pportdata *ppd, enum ib_event_type ev)
+{
+   struct ib_event event;
+   struct qib_devdata *dd = ppd-dd;
+
+   event.device = dd-verbs_dev.ibdev;
+   event.element.port_num = ppd-port;
+   event.event = ev;
+   ib_dispatch_event(event);
+}
+
+void qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs)
+{
+   struct qib_devdata *dd = ppd-dd;
+   unsigned long flags;
+   u32 lstate;
+   u8 ltstate;
+
+   lstate = dd-f_iblink_state(ibcs); /* linkstate */
+   ltstate = dd-f_ibphys_portstate(ibcs);
+
+   /*
+* If linkstate transitions into INIT from any of the various down
+* states, or if it transitions from any of the up (INIT or better)
+* states into any of the down states (except link recovery), then
+* call the chip-specific code to take appropriate actions.
+*/
+   if (lstate = IB_PORT_INIT  (ppd-lflags  QIBL_LINKDOWN) 
+   ltstate == IB_PHYSPORTSTATE_LINKUP) {
+   /* transitioned to UP */
+   if (dd-f_ib_updown(ppd, 1, ibcs))
+   goto skip_ibchange; /* chip-code handled */
+   } else if (ppd-lflags  (QIBL_LINKINIT | QIBL_LINKARMED |
+  QIBL_LINKACTIVE | QIBL_IB_FORCE_NOTIFY)) {
+   if (ltstate != IB_PHYSPORTSTATE_LINKUP 
+   ltstate = IB_PHYSPORTSTATE_CFG_TRAIN 
+   dd-f_ib_updown(ppd, 0, ibcs))
+   goto skip_ibchange; /* chip-code handled */
+   qib_set_uevent_bits(ppd, _QIB_EVENT_LINKDOWN_BIT);
+   }
+
+   if (lstate != IB_PORT_DOWN) {
+   /* lstate is INIT, ARMED, or ACTIVE */
+   if (lstate != IB_PORT_ACTIVE) {
+   *ppd-statusp = ~QIB_STATUS_IB_READY;
+   if (ppd-lflags  QIBL_LINKACTIVE

[PATCH v2 22/51] IB/qib: Add qib_keys.c

2009-12-03 Thread Ralph Campbell
creates the qib_keys.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_keys.c |  278 ++
 1 files changed, 278 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_keys.c

diff --git a/drivers/infiniband/hw/qib/qib_keys.c 
b/drivers/infiniband/hw/qib/qib_keys.c
new file mode 100644
index 000..e2b42e5
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_keys.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2006, 2007, 2009 QLogic Corporation. All rights reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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 qib.h
+
+/**
+ * qib_alloc_lkey - allocate an lkey
+ * @rkt: lkey table in which to allocate the lkey
+ * @mr: memory region that this lkey protects
+ *
+ * Returns 1 if successful, otherwise returns 0.
+ */
+
+int qib_alloc_lkey(struct qib_lkey_table *rkt, struct qib_mregion *mr)
+{
+   unsigned long flags;
+   u32 r;
+   u32 n;
+   int ret;
+
+   spin_lock_irqsave(rkt-lock, flags);
+
+   /* Find the next available LKEY */
+   r = rkt-next;
+   n = r;
+   for (;;) {
+   if (rkt-table[r] == NULL)
+   break;
+   r = (r + 1)  (rkt-max - 1);
+   if (r == n) {
+   spin_unlock_irqrestore(rkt-lock, flags);
+   qib_dbg(LKEY table full\n);
+   ret = 0;
+   goto bail;
+   }
+   }
+   rkt-next = (r + 1)  (rkt-max - 1);
+   /*
+* Make sure lkey is never zero which is reserved to indicate an
+* unrestricted LKEY.
+*/
+   rkt-gen++;
+   mr-lkey = (r  (32 - ib_qib_lkey_table_size)) |
+   1  (24 - ib_qib_lkey_table_size)) - 1)  rkt-gen)
+ 8);
+   if (mr-lkey == 0) {
+   mr-lkey |= 1  8;
+   rkt-gen++;
+   }
+   rkt-table[r] = mr;
+   spin_unlock_irqrestore(rkt-lock, flags);
+
+   ret = 1;
+
+bail:
+   return ret;
+}
+
+/**
+ * qib_free_lkey - free an lkey
+ * @rkt: table from which to free the lkey
+ * @lkey: lkey id to free
+ */
+int qib_free_lkey(struct qib_ibdev *dev, struct qib_mregion *mr)
+{
+   unsigned long flags;
+   u32 lkey = mr-lkey;
+   u32 r;
+   int ret;
+
+   spin_lock_irqsave(dev-lk_table.lock, flags);
+   if (lkey == 0) {
+   if (dev-dma_mr  dev-dma_mr == mr) {
+   ret = atomic_read(dev-dma_mr-refcount);
+   if (!ret)
+   dev-dma_mr = NULL;
+   } else
+   ret = 0;
+   } else {
+   r = lkey  (32 - ib_qib_lkey_table_size);
+   ret = atomic_read(dev-lk_table.table[r]-refcount);
+   if (!ret)
+   dev-lk_table.table[r] = NULL;
+   }
+   spin_unlock_irqrestore(dev-lk_table.lock, flags);
+
+   if (ret) {
+   qib_dbg(MR busy (LKEY %x cnt %u)\n, lkey, ret);
+   ret = -EBUSY;
+   }
+   return ret;
+}
+
+/**
+ * qib_lkey_ok - check IB SGE for validity and initialize
+ * @rkt: table containing lkey to check SGE against
+ * @isge: outgoing internal SGE
+ * @sge: SGE to check
+ * @acc: access flags
+ *
+ * Return 1 if valid and successful, otherwise returns 0.
+ *
+ * Check the IB SGE for validity and initialize our internal version
+ * of it.
+ */
+int qib_lkey_ok(struct qib_lkey_table *rkt, struct qib_pd *pd,
+   struct qib_sge *isge, struct ib_sge *sge, int acc

[PATCH v2 23/51] IB/qib: Add qib_mad.c

2009-12-03 Thread Ralph Campbell
creates the qib_mad.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_mad.c | 1867 +++
 1 files changed, 1867 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mad.c

diff --git a/drivers/infiniband/hw/qib/qib_mad.c 
b/drivers/infiniband/hw/qib/qib_mad.c
new file mode 100644
index 000..d6fd6e1
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mad.c
@@ -0,0 +1,1867 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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 rdma/ib_smi.h
+
+#include qib.h
+#include qib_mad.h
+
+static int reply(struct ib_smp *smp)
+{
+   /*
+* The verbs framework will handle the directed/LID route
+* packet changes.
+*/
+   smp-method = IB_MGMT_METHOD_GET_RESP;
+   if (smp-mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+   smp-status |= IB_SMP_DIRECTION;
+   return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
+}
+
+static void qib_send_trap(struct qib_ibport *ibp, void *data, unsigned len)
+{
+   struct ib_mad_send_buf *send_buf;
+   struct ib_mad_agent *agent;
+   struct ib_smp *smp;
+   int ret;
+   unsigned long flags;
+   unsigned long timeout;
+
+   agent = ibp-send_agent;
+   if (!agent)
+   return;
+
+   /* o14-3.2.1 */
+   if (!(ppd_from_ibp(ibp)-lflags  QIBL_LINKACTIVE))
+   return;
+
+   /* o14-2 */
+   if (ibp-trap_timeout  time_before(jiffies, ibp-trap_timeout))
+   return;
+
+   send_buf = ib_create_send_mad(agent, 0, 0, 0, IB_MGMT_MAD_HDR,
+ IB_MGMT_MAD_DATA, GFP_ATOMIC);
+   if (IS_ERR(send_buf))
+   return;
+
+   smp = send_buf-mad;
+   smp-base_version = IB_MGMT_BASE_VERSION;
+   smp-mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+   smp-class_version = 1;
+   smp-method = IB_MGMT_METHOD_TRAP;
+   ibp-tid++;
+   smp-tid = cpu_to_be64(ibp-tid);
+   smp-attr_id = IB_SMP_ATTR_NOTICE;
+   /* o14-1: smp-mkey = 0; */
+   memcpy(smp-data, data, len);
+
+   spin_lock_irqsave(ibp-lock, flags);
+   if (!ibp-sm_ah) {
+   if (ibp-sm_lid != be16_to_cpu(IB_LID_PERMISSIVE)) {
+   struct ib_ah *ah;
+   struct ib_ah_attr attr;
+
+   memset(attr, 0, sizeof attr);
+   attr.dlid = ibp-sm_lid;
+   attr.port_num = ppd_from_ibp(ibp)-port;
+   ah = ib_create_ah(ibp-qp0-ibqp.pd, attr);
+   if (IS_ERR(ah))
+   ret = -EINVAL;
+   else {
+   send_buf-ah = ah;
+   ibp-sm_ah = to_iah(ah);
+   ret = 0;
+   }
+   } else
+   ret = -EINVAL;
+   } else {
+   send_buf-ah = ibp-sm_ah-ibah;
+   ret = 0;
+   }
+   spin_unlock_irqrestore(ibp-lock, flags);
+
+   if (!ret)
+   ret = ib_post_send_mad(send_buf, NULL);
+   if (!ret) {
+   /* 4.096 usec. */
+   timeout = (4096 * (1UL  ibp-subnet_timeout)) / 1000;
+   ibp-trap_timeout = jiffies + usecs_to_jiffies(timeout);
+   } else {
+   ib_free_send_mad(send_buf);
+   ibp-trap_timeout = 0;
+   }
+}
+
+/*
+ * Send a bad [PQ]_Key

[PATCH v2 24/51] IB/qib: Add qib_mad.h

2009-12-03 Thread Ralph Campbell
creates the qib_mad.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_mad.h |  333 +++
 1 files changed, 333 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mad.h

diff --git a/drivers/infiniband/hw/qib/qib_mad.h 
b/drivers/infiniband/hw/qib/qib_mad.h
new file mode 100644
index 000..57cab0d
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mad.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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.
+ */
+
+#define IB_SMP_UNSUP_VERSIONcpu_to_be16(0x0004)
+#define IB_SMP_UNSUP_METHOD cpu_to_be16(0x0008)
+#define IB_SMP_UNSUP_METH_ATTR  cpu_to_be16(0x000C)
+#define IB_SMP_INVALID_FIELDcpu_to_be16(0x001C)
+
+struct ib_node_info {
+   u8 base_version;
+   u8 class_version;
+   u8 node_type;
+   u8 num_ports;
+   __be64 sys_guid;
+   __be64 node_guid;
+   __be64 port_guid;
+   __be16 partition_cap;
+   __be16 device_id;
+   __be32 revision;
+   u8 local_port_num;
+   u8 vendor_id[3];
+} __attribute__ ((packed));
+
+struct ib_mad_notice_attr {
+   u8 generic_type;
+   u8 prod_type_msb;
+   __be16 prod_type_lsb;
+   __be16 trap_num;
+   __be16 issuer_lid;
+   __be16 toggle_count;
+
+   union {
+   struct {
+   u8  details[54];
+   } raw_data;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* where violation happened */
+   u8  port_num;   /* where violation happened */
+   } __attribute__ ((packed)) ntc_129_131;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* LID where change occured */
+   u8  reserved2;
+   u8  local_changes;  /* low bit - local changes */
+   __be32  new_cap_mask;   /* new capability mask */
+   u8  reserved3;
+   u8  change_flags;   /* low 3 bits only */
+   } __attribute__ ((packed)) ntc_144;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* lid where sys guid changed */
+   __be16  reserved2;
+   __be64  new_sys_guid;
+   } __attribute__ ((packed)) ntc_145;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;
+   __be16  dr_slid;
+   u8  method;
+   u8  reserved2;
+   __be16  attr_id;
+   __be32  attr_mod;
+   __be64  mkey;
+   u8  reserved3;
+   u8  dr_trunc_hop;
+   u8  dr_rtn_path[30];
+   } __attribute__ ((packed)) ntc_256;
+
+   struct {
+   __be16  reserved;
+   __be16  lid1;
+   __be16  lid2;
+   __be32  key;
+   __be32  sl_qp1; /* SL: high 4 bits */
+   __be32  qp2;/* high 8 bits reserved */
+   union ib_gidgid1;
+   union ib_gidgid2

[PATCH v2 25/51] IB/qib: Add qib_mmap.c

2009-12-03 Thread Ralph Campbell
creates the qib_mmap.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_mmap.c |  173 ++
 1 files changed, 173 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mmap.c

diff --git a/drivers/infiniband/hw/qib/qib_mmap.c 
b/drivers/infiniband/hw/qib/qib_mmap.c
new file mode 100644
index 000..ae15d38
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mmap.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. 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/module.h
+#include linux/vmalloc.h
+#include linux/mm.h
+#include linux/errno.h
+#include asm/pgtable.h
+
+#include qib_verbs.h
+
+/**
+ * qib_release_mmap_info - free mmap info structure
+ * @ref: a pointer to the kref within struct qib_mmap_info
+ */
+void qib_release_mmap_info(struct kref *ref)
+{
+   struct qib_mmap_info *ip =
+   container_of(ref, struct qib_mmap_info, ref);
+   struct qib_ibdev *dev = to_idev(ip-context-device);
+
+   spin_lock_irq(dev-pending_lock);
+   list_del(ip-pending_mmaps);
+   spin_unlock_irq(dev-pending_lock);
+
+   vfree(ip-obj);
+   kfree(ip);
+}
+
+/*
+ * open and close keep track of how many times the CQ is mapped,
+ * to avoid releasing it.
+ */
+static void qib_vma_open(struct vm_area_struct *vma)
+{
+   struct qib_mmap_info *ip = vma-vm_private_data;
+
+   kref_get(ip-ref);
+}
+
+static void qib_vma_close(struct vm_area_struct *vma)
+{
+   struct qib_mmap_info *ip = vma-vm_private_data;
+
+   kref_put(ip-ref, qib_release_mmap_info);
+}
+
+static struct vm_operations_struct qib_vm_ops = {
+   .open = qib_vma_open,
+   .close =qib_vma_close,
+};
+
+/**
+ * qib_mmap - create a new mmap region
+ * @context: the IB user context of the process making the mmap() call
+ * @vma: the VMA to be initialized
+ * Return zero if the mmap is OK. Otherwise, return an errno.
+ */
+int qib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
+{
+   struct qib_ibdev *dev = to_idev(context-device);
+   unsigned long offset = vma-vm_pgoff  PAGE_SHIFT;
+   unsigned long size = vma-vm_end - vma-vm_start;
+   struct qib_mmap_info *ip, *pp;
+   int ret = -EINVAL;
+
+   /*
+* Search the device's list of objects waiting for a mmap call.
+* Normally, this list is very short since a call to create a
+* CQ, QP, or SRQ is soon followed by a call to mmap().
+*/
+   spin_lock_irq(dev-pending_lock);
+   list_for_each_entry_safe(ip, pp, dev-pending_mmaps,
+pending_mmaps) {
+   /* Only the creator is allowed to mmap the object */
+   if (context != ip-context || (__u64) offset != ip-offset)
+   continue;
+   /* Don't allow a mmap larger than the object. */
+   if (size  ip-size)
+   break;
+
+   list_del_init(ip-pending_mmaps);
+   spin_unlock_irq(dev-pending_lock);
+
+   ret = remap_vmalloc_range(vma, ip-obj, 0);
+   if (ret)
+   goto done;
+   vma-vm_ops = qib_vm_ops;
+   vma-vm_private_data = ip;
+   qib_vma_open(vma);
+   goto done;
+   }
+   spin_unlock_irq(dev-pending_lock);
+done:
+   return ret;
+}
+
+/*
+ * Allocate information for qib_mmap
+ */
+struct qib_mmap_info *qib_create_mmap_info(struct qib_ibdev *dev,
+  u32

[PATCH v2 26/51] IB/qib: Add qib_mr.c

2009-12-03 Thread Ralph Campbell
creates the qib_mr.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_mr.c |  455 
 1 files changed, 455 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mr.c

diff --git a/drivers/infiniband/hw/qib/qib_mr.c 
b/drivers/infiniband/hw/qib/qib_mr.c
new file mode 100644
index 000..f283c3b
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mr.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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 rdma/ib_umem.h
+#include rdma/ib_smi.h
+
+#include qib.h
+
+/* Fast memory region */
+struct qib_fmr {
+   struct ib_fmr ibfmr;
+   u8 page_shift;
+   struct qib_mregion mr;/* must be last */
+};
+
+static inline struct qib_fmr *to_ifmr(struct ib_fmr *ibfmr)
+{
+   return container_of(ibfmr, struct qib_fmr, ibfmr);
+}
+
+/**
+ * qib_get_dma_mr - get a DMA memory region
+ * @pd: protection domain for this memory region
+ * @acc: access flags
+ *
+ * Returns the memory region on success, otherwise returns an errno.
+ * Note that all DMA addresses should be created via the
+ * struct ib_dma_mapping_ops functions (see qib_dma.c).
+ */
+struct ib_mr *qib_get_dma_mr(struct ib_pd *pd, int acc)
+{
+   struct qib_ibdev *dev = to_idev(pd-device);
+   struct qib_mr *mr;
+   struct ib_mr *ret;
+   unsigned long flags;
+
+   if (to_ipd(pd)-user) {
+   ret = ERR_PTR(-EPERM);
+   goto bail;
+   }
+
+   mr = kzalloc(sizeof *mr, GFP_KERNEL);
+   if (!mr) {
+   ret = ERR_PTR(-ENOMEM);
+   goto bail;
+   }
+
+   mr-mr.access_flags = acc;
+   atomic_set(mr-mr.refcount, 0);
+
+   spin_lock_irqsave(dev-lk_table.lock, flags);
+   if (!dev-dma_mr)
+   dev-dma_mr = mr-mr;
+   spin_unlock_irqrestore(dev-lk_table.lock, flags);
+
+   ret = mr-ibmr;
+
+bail:
+   return ret;
+}
+
+static struct qib_mr *alloc_mr(int count, struct qib_lkey_table *lk_table)
+{
+   struct qib_mr *mr;
+   int m, i = 0;
+
+   /* Allocate struct plus pointers to first level page tables. */
+   m = (count + QIB_SEGSZ - 1) / QIB_SEGSZ;
+   mr = kmalloc(sizeof *mr + m * sizeof mr-mr.map[0], GFP_KERNEL);
+   if (!mr)
+   goto done;
+
+   /* Allocate first level page tables. */
+   for (; i  m; i++) {
+   mr-mr.map[i] = kmalloc(sizeof *mr-mr.map[0], GFP_KERNEL);
+   if (!mr-mr.map[i])
+   goto bail;
+   }
+   mr-mr.mapsz = m;
+
+   /*
+* ib_reg_phys_mr() will initialize mr-ibmr except for
+* lkey and rkey.
+*/
+   if (!qib_alloc_lkey(lk_table, mr-mr))
+   goto bail;
+   mr-ibmr.lkey = mr-mr.lkey;
+   mr-ibmr.rkey = mr-mr.lkey;
+
+   atomic_set(mr-mr.refcount, 0);
+   goto done;
+
+bail:
+   while (i)
+   kfree(mr-mr.map[--i]);
+   kfree(mr);
+   mr = NULL;
+
+done:
+   return mr;
+}
+
+/**
+ * qib_reg_phys_mr - register a physical memory region
+ * @pd: protection domain for this memory region
+ * @buffer_list: pointer to the list of physical buffers to register
+ * @num_phys_buf: the number of physical buffers to register
+ * @iova_start: the starting address passed over IB which maps to this MR
+ *
+ * Returns the memory region on success, otherwise returns an errno.
+ */
+struct ib_mr *qib_reg_phys_mr(struct ib_pd *pd

[PATCH v2 27/51] IB/qib: Add qib_pcie.c

2009-12-03 Thread Ralph Campbell
creates the qib_pcie.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_pcie.c |  810 ++
 1 files changed, 810 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_pcie.c

diff --git a/drivers/infiniband/hw/qib/qib_pcie.c 
b/drivers/infiniband/hw/qib/qib_pcie.c
new file mode 100644
index 000..714cad4
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_pcie.c
@@ -0,0 +1,810 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. 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/pci.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/vmalloc.h
+#include linux/aer.h
+
+#include qib.h
+
+/*
+ * This file contains PCIe utility routines that are common to the
+ * various QLogic InfiniPath adapters
+ */
+
+/*
+ * Code to adjust PCIe capabilities.
+ * To minimize the change footprint, we call it
+ * from qib_pcie_params, which every chip-specific
+ * file calls, even though this violates some
+ * expectations of harmlessness.
+ */
+static int qib_tune_pcie_caps(struct qib_devdata *);
+static int qib_tune_pcie_coalesce(struct qib_devdata *);
+
+/*
+ * Do all the common PCIe setup and initialization.
+ * devdata is not yet allocated, and is not allocated until after this
+ * routine returns success.  Therefore qib_dev_err() can't be used for error
+ * printing.
+ */
+int qib_pcie_init(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+   int ret;
+
+   ret = pci_enable_device(pdev);
+   if (ret) {
+   /*
+* This can happen (in theory) iff:
+* We did a chip reset, and then failed to reprogram the
+* BAR, or the chip reset due to an internal error.  We then
+* unloaded the driver and reloaded it.
+*
+* Both reset cases set the BAR back to initial state.  For
+* the latter case, the AER sticky error bit at offset 0x718
+* should be set, but the Linux kernel doesn't yet know
+* about that, it appears.  If the original BAR was retained
+* in the kernel data structures, this may be OK.
+*/
+   qib_early_err(pdev-dev, pci enable failed: error %d\n,
+ -ret);
+   goto done;
+   }
+
+   ret = pci_request_regions(pdev, QIB_DRV_NAME);
+   if (ret) {
+   qib_devinfo(pdev, pci_request_regions fails: err %d\n, -ret);
+   goto bail;
+   }
+
+   ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+   if (ret) {
+   /*
+* If the 64 bit setup fails, try 32 bit.  Some systems
+* do not setup 64 bit maps on systems with 2GB or less
+* memory installed.
+*/
+   ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+   if (ret) {
+   qib_devinfo(pdev, Unable to set DMA mask: %d\n, ret);
+   goto bail;
+   }
+   qib_dbg(No 64bit DMA mask, used 32 bit mask\n);
+   ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+   } else
+   ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+   if (ret)
+   qib_early_err(pdev-dev,
+ Unable to set DMA consistent mask: %d\n, ret);
+
+   pci_set_master(pdev);
+   ret = pci_enable_pcie_error_reporting(pdev);
+   if (ret)
+   qib_early_err(pdev-dev

[PATCH v2 28/51] IB/qib: Add qib_pio_copy.c

2009-12-03 Thread Ralph Campbell
creates the qib_pio_copy.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_pio_copy.c |   64 ++
 1 files changed, 64 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_pio_copy.c

diff --git a/drivers/infiniband/hw/qib/qib_pio_copy.c 
b/drivers/infiniband/hw/qib/qib_pio_copy.c
new file mode 100644
index 000..10b8c44
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_pio_copy.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009 QLogic Corporation. 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 qib.h
+
+/**
+ * qib_pio_copy - copy data to MMIO space, in multiples of 32-bits
+ * @to: destination, in MMIO space (must be 64-bit aligned)
+ * @from: source (must be 64-bit aligned)
+ * @count: number of 32-bit quantities to copy
+ *
+ * Copy data from kernel space to MMIO space, in multiples of 32 bits at a
+ * time.  Order of access is not guaranteed, nor is a memory barrier
+ * performed afterwards.
+ */
+void qib_pio_copy(void __iomem *to, const void *from, size_t count)
+{
+#ifdef CONFIG_64BIT
+   u64 __iomem *dst = to;
+   const u64 *src = from;
+   const u64 *end = src + (count  1);
+
+   while (src  end)
+   __raw_writeq(*src++, dst++);
+   if (count  1)
+   __raw_writel(*(const u32 *)src, dst);
+#else
+   u32 __iomem *dst = to;
+   const u32 *src = from;
+   const u32 *end = src + count;
+
+   while (src  end)
+   __raw_writel(*src++, dst++);
+#endif
+}

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 29/51] IB/qib: Add qib_qp.c

2009-12-03 Thread Ralph Campbell
creates the qib_qp.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_qp.c | 1241 
 1 files changed, 1241 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qp.c

diff --git a/drivers/infiniband/hw/qib/qib_qp.c 
b/drivers/infiniband/hw/qib/qib_qp.c
new file mode 100644
index 000..d0ccbf5
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qp.c
@@ -0,0 +1,1241 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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/err.h
+#include linux/vmalloc.h
+
+#include qib.h
+
+#define BITS_PER_PAGE   (PAGE_SIZE*BITS_PER_BYTE)
+#define BITS_PER_PAGE_MASK  (BITS_PER_PAGE-1)
+
+static inline unsigned mk_qpn(struct qib_qpn_table *qpt,
+ struct qpn_map *map, unsigned off)
+{
+   return (map - qpt-map) * BITS_PER_PAGE + off;
+}
+
+static inline unsigned find_next_offset(struct qib_qpn_table *qpt,
+   struct qpn_map *map, unsigned off,
+   unsigned r)
+{
+   if (qpt-mask) {
+   off++;
+   if ((off  qpt-mask)  1 != r)
+   off = ((off  qpt-mask) ?
+   (off | qpt-mask) + 1 : off) | (r  1);
+   } else
+   off = find_next_zero_bit(map-page, BITS_PER_PAGE, off);
+   return off;
+}
+
+/*
+ * Convert the AETH credit code into the number of credits.
+ */
+static u32 credit_table[31] = {
+   0,  /* 0 */
+   1,  /* 1 */
+   2,  /* 2 */
+   3,  /* 3 */
+   4,  /* 4 */
+   6,  /* 5 */
+   8,  /* 6 */
+   12, /* 7 */
+   16, /* 8 */
+   24, /* 9 */
+   32, /* A */
+   48, /* B */
+   64, /* C */
+   96, /* D */
+   128,/* E */
+   192,/* F */
+   256,/* 10 */
+   384,/* 11 */
+   512,/* 12 */
+   768,/* 13 */
+   1024,   /* 14 */
+   1536,   /* 15 */
+   2048,   /* 16 */
+   3072,   /* 17 */
+   4096,   /* 18 */
+   6144,   /* 19 */
+   8192,   /* 1A */
+   12288,  /* 1B */
+   16384,  /* 1C */
+   24576,  /* 1D */
+   32768   /* 1E */
+};
+
+static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map)
+{
+   unsigned long page = get_zeroed_page(GFP_KERNEL);
+
+   /*
+* Free the page if someone raced with us installing it.
+*/
+
+   spin_lock(qpt-lock);
+   if (map-page)
+   free_page(page);
+   else
+   map-page = (void *)page;
+   spin_unlock(qpt-lock);
+}
+
+/*
+ * Allocate the next available QPN or
+ * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI.
+ */
+static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt,
+enum ib_qp_type type, u8 port)
+{
+   u32 i, offset, max_scan, qpn;
+   struct qpn_map *map;
+   u32 ret;
+   int

[PATCH v2 31/51] IB/qib: Add qib_qsfp.h

2009-12-03 Thread Ralph Campbell
creates the qib_qsfp.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_qsfp.h |  183 ++
 1 files changed, 183 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qsfp.h

diff --git a/drivers/infiniband/hw/qib/qib_qsfp.h 
b/drivers/infiniband/hw/qib/qib_qsfp.h
new file mode 100644
index 000..01ea507
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qsfp.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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.
+ */
+/* QSFP support common definitions, for ib_qib driver */
+
+#define QSFP_DEV 0xA0
+#define QSFP_PWR_LAG_MSEC 2000
+
+/*
+ * Below are masks for various QSFP signals, for Port 1.
+ * Port2 equivalents are shifted by QSFP_GPIO_PORT2_SHIFT.
+ * _N means asserted low
+ */
+#define QSFP_GPIO_MOD_SEL_N (4)
+#define QSFP_GPIO_MOD_PRS_N (8)
+#define QSFP_GPIO_INT_N (0x10)
+#define QSFP_GPIO_MOD_RST_N (0x20)
+#define QSFP_GPIO_LP_MODE (0x40)
+#define QSFP_GPIO_PORT2_SHIFT 5
+
+#define QSFP_PAGESIZE 128
+/* Defined fields that QLogic requires of qualified cables */
+/* Byte 0 is Identifier, not checked */
+/* Byte 1 is reserved status MSB */
+/* Byte 2 is status LSB We only care that D2 Flat Mem is set. */
+/*
+ * Rest of first 128 not used, although 127 is reserved for page select
+ * if module is not Flat memory.
+ */
+/* Byte 128 is Identifier: must be 0x0c for QSFP, or 0x0d for QSFP+ */
+#define QSFP_MOD_ID_OFFS 128
+/*
+ * Byte 129 is Extended Identifier. We only care about D7,D6: Power class
+ *  0:1.5W, 1:2.0W, 2:2.5W, 3:3.5W
+ */
+#define QSFP_MOD_PWR_OFFS 129
+/* Byte 130 is Connector type. Not QLogic req'd */
+/* Bytes 131..138 are Transceiver types, bit maps for various tech, none IB */
+/* Byte 139 is encoding. code 0x01 is 8b10b. Not QLogic req'd */
+/* byte 140 is nominal bit-rate, in units of 100Mbits/sec Not QLogic req'd */
+/* Byte 141 is Extended Rate Select. Not QLogic req'd */
+/* Bytes 142..145 are lengths for various fiber types. Not QLogic req'd */
+/* Byte 146 is length for Copper. Units of 1 meter */
+#define QSFP_MOD_LEN_OFFS 146
+/*
+ * Byte 147 is Device technology. D0..3 not Qlogc req'd
+ * D4..7 select from 15 choices, translated by table:
+ */
+#define QSFP_MOD_TECH_OFFS 147
+extern const char *const qib_qsfp_devtech[16];
+/* Length is only valid if technology is copper */
+#define QSFP_IS_CU(tech) ((0xED00  ((tech)  4))  1)
+#define QSFP_TECH_1490 9
+
+#define QSFP_OUI(oui) (((unsigned)oui[0]  16) | ((unsigned)oui[1]  8) | \
+   oui[2])
+#define QSFP_OUI_AMPHENOL 0x415048
+#define QSFP_OUI_FINISAR  0x009065
+#define QSFP_OUI_GORE 0x002177
+
+/* Bytes 148..163 are Vendor Name, Left-justified Blank-filled */
+#define QSFP_VEND_OFFS 148
+#define QSFP_VEND_LEN 16
+/* Byte 164 is IB Extended tranceiver codes Bits D0..3 are SDR,DDR,QDR,EDR */
+#define QSFP_IBXCV_OFFS 164
+/* Bytes 165..167 are Vendor OUI number */
+#define QSFP_VOUI_OFFS 165
+#define QSFP_VOUI_LEN 3
+/* Bytes 168..183 are Vendor Part Number, string */
+#define QSFP_PN_OFFS 168
+#define QSFP_PN_LEN 16
+/* Bytes 184,185 are Vendor Rev. Left Justified, Blank-filled */
+#define QSFP_REV_OFFS 184
+#define QSFP_REV_LEN 2
+/*
+ * Bytes 186,187 are Wavelength, if Optical. Not Qlogic req'd
+ *  If copper, they are attenuation in dB:
+ * Byte 186 is at 2.5Gb/sec (SDR), Byte 187 at 5.0Gb/sec (DDR)
+ */
+#define QSFP_ATTEN_OFFS 186
+#define QSFP_ATTEN_LEN 2
+/* Bytes 188,189 are Wavelength tolerance

[PATCH v2 33/51] IB/qib: Add qib_ruc.c

2009-12-03 Thread Ralph Campbell
creates the qib_ruc.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_ruc.c |  817 +++
 1 files changed, 817 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_ruc.c

diff --git a/drivers/infiniband/hw/qib/qib_ruc.c 
b/drivers/infiniband/hw/qib/qib_ruc.c
new file mode 100644
index 000..eb78d93
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_ruc.c
@@ -0,0 +1,817 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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/spinlock.h
+
+#include qib.h
+#include qib_mad.h
+
+/*
+ * Convert the AETH RNR timeout code into the number of microseconds.
+ */
+const u32 ib_qib_rnr_table[32] = {
+   655360, /* 00: 655.36 */
+   10, /* 01:.01 */
+   20, /* 02 .02 */
+   30, /* 03:.03 */
+   40, /* 04:.04 */
+   60, /* 05:.06 */
+   80, /* 06:.08 */
+   120,/* 07:.12 */
+   160,/* 08:.16 */
+   240,/* 09:.24 */
+   320,/* 0A:.32 */
+   480,/* 0B:.48 */
+   640,/* 0C:.64 */
+   960,/* 0D:.96 */
+   1280,   /* 0E:   1.28 */
+   1920,   /* 0F:   1.92 */
+   2560,   /* 10:   2.56 */
+   3840,   /* 11:   3.84 */
+   5120,   /* 12:   5.12 */
+   7680,   /* 13:   7.68 */
+   10240,  /* 14:  10.24 */
+   15360,  /* 15:  15.36 */
+   20480,  /* 16:  20.48 */
+   30720,  /* 17:  30.72 */
+   40960,  /* 18:  40.96 */
+   61440,  /* 19:  61.44 */
+   81920,  /* 1A:  81.92 */
+   122880, /* 1B: 122.88 */
+   163840, /* 1C: 163.84 */
+   245760, /* 1D: 245.76 */
+   327680, /* 1E: 327.68 */
+   491520  /* 1F: 491.52 */
+};
+
+/*
+ * Validate a RWQE and fill in the SGE state.
+ * Return 1 if OK.
+ */
+static int qib_init_sge(struct qib_qp *qp, struct qib_rwqe *wqe)
+{
+   int i, j, ret;
+   struct ib_wc wc;
+   struct qib_lkey_table *rkt;
+   struct qib_pd *pd;
+   struct qib_sge_state *ss;
+
+   rkt = to_idev(qp-ibqp.device)-lk_table;
+   pd = to_ipd(qp-ibqp.srq ? qp-ibqp.srq-pd : qp-ibqp.pd);
+   ss = qp-r_sge;
+   ss-sg_list = qp-r_sg_list;
+   qp-r_len = 0;
+   for (i = j = 0; i  wqe-num_sge; i++) {
+   if (wqe-sg_list[i].length == 0)
+   continue;
+   /* Check LKEY */
+   if (!qib_lkey_ok(rkt, pd, j ? ss-sg_list[j - 1] : ss-sge,
+wqe-sg_list[i], IB_ACCESS_LOCAL_WRITE))
+   goto bad_lkey;
+   qp-r_len += wqe-sg_list[i].length;
+   j++;
+   }
+   ss-num_sge = j;
+   ss-total_len = qp-r_len;
+   ret = 1;
+   goto bail;
+
+bad_lkey:
+   while (j) {
+   struct qib_sge *sge = --j ? ss-sg_list[j - 1] : ss-sge;
+
+   atomic_dec(sge-mr-refcount);
+   }
+   ss-num_sge = 0;
+   memset(wc, 0, sizeof(wc));
+   wc.wr_id = wqe-wr_id;
+   wc.status = IB_WC_LOC_PROT_ERR;
+   wc.opcode = IB_WC_RECV;
+   wc.qp = qp-ibqp;
+   /* Signal solicited completion event. */
+   qib_cq_enter(to_icq(qp-ibqp.recv_cq), wc, 1);
+   ret = 0;
+bail:
+   return ret;
+}
+
+/**
+ * qib_get_rwqe - copy the next RWQE into the QP's RWQE
+ * @qp: the QP
+ * @wr_id_only: update qp-r_wr_id only, not qp-r_sge
+ *
+ * Return -1 if there is a local error, 0 if no RWQE is available

[PATCH v2 34/51] IB/qib: Add qib_sd7220.c

2009-12-03 Thread Ralph Campbell
creates the qib_sd7220.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_sd7220.c | 1442 
 1 files changed, 1442 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sd7220.c

diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c 
b/drivers/infiniband/hw/qib/qib_sd7220.c
new file mode 100644
index 000..2230a09
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sd7220.c
@@ -0,0 +1,1442 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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.
+ */
+/*
+ * This file contains all of the code that is specific to the SerDes
+ * on the QLogic_IB 7220 chip.
+ */
+
+#include linux/pci.h
+#include linux/delay.h
+
+#include qib.h
+#include qib_7220.h
+
+/*
+ * Same as in qib_iba7220.c, but just the registers needed here.
+ * Could move whole set to qib_7220.h, but decided better to keep
+ * local.
+ */
+#define KREG_IDX(regname) (QIB_7220_##regname##_OFFS / sizeof(u64))
+#define kr_hwerrclear KREG_IDX(HwErrClear)
+#define kr_hwerrmask KREG_IDX(HwErrMask)
+#define kr_hwerrstatus KREG_IDX(HwErrStatus)
+#define kr_ibcstatus KREG_IDX(IBCStatus)
+#define kr_ibserdesctrl KREG_IDX(IBSerDesCtrl)
+#define kr_scratch KREG_IDX(Scratch)
+#define kr_xgxs_cfg KREG_IDX(XGXSCfg)
+/* these are used only here, not in qib_iba7220.c */
+#define kr_ibsd_epb_access_ctrl KREG_IDX(ibsd_epb_access_ctrl)
+#define kr_ibsd_epb_transaction_reg KREG_IDX(ibsd_epb_transaction_reg)
+#define kr_pciesd_epb_transaction_reg KREG_IDX(pciesd_epb_transaction_reg)
+#define kr_pciesd_epb_access_ctrl KREG_IDX(pciesd_epb_access_ctrl)
+#define kr_serdes_ddsrxeq0 KREG_IDX(SerDes_DDSRXEQ0)
+
+/*
+ * The IBSerDesMappTable is a memory that holds values to be stored in
+ * various SerDes registers by IBC.
+ */
+#define kr_serdes_maptable KREG_IDX(IBSerDesMappTable)
+
+/*
+ * Below used for sdnum parameter, selecting one of the two sections
+ * used for PCIe, or the single SerDes used for IB.
+ */
+#define PCIE_SERDES0 0
+#define PCIE_SERDES1 1
+
+/*
+ * The EPB requires addressing in a particular form. EPB_LOC() is intended
+ * to make #definitions a little more readable.
+ */
+#define EPB_ADDR_SHF 8
+#define EPB_LOC(chn, elt, reg) \
+   (((elt  0xf) | ((chn  7)  4) | ((reg  0x3f)  9))  \
+EPB_ADDR_SHF)
+#define EPB_IB_QUAD0_CS_SHF (25)
+#define EPB_IB_QUAD0_CS (1U   EPB_IB_QUAD0_CS_SHF)
+#define EPB_IB_UC_CS_SHF (26)
+#define EPB_PCIE_UC_CS_SHF (27)
+#define EPB_GLOBAL_WR (1U  (EPB_ADDR_SHF + 8))
+
+/* Forward declarations. */
+static int qib_sd7220_reg_mod(struct qib_devdata *dd, int sdnum, u32 loc,
+ u32 data, u32 mask);
+static int ibsd_mod_allchnls(struct qib_devdata *dd, int loc, int val,
+int mask);
+static int qib_sd_trimdone_poll(struct qib_devdata *dd);
+static void qib_sd_trimdone_monitor(struct qib_devdata *dd, const char *where);
+static int qib_sd_setvals(struct qib_devdata *dd);
+static int qib_sd_early(struct qib_devdata *dd);
+static int qib_sd_dactrim(struct qib_devdata *dd);
+static int qib_internal_presets(struct qib_devdata *dd);
+/* Tweak the register (CMUCTRL5) that contains the TRIMSELF controls */
+static int qib_sd_trimself(struct qib_devdata *dd, int val);
+static int epb_access(struct qib_devdata *dd, int sdnum, int claim);
+
+/*
+ * Below keeps track of whether the once per power-on initialization has
+ * been done, because uC code Version 1.32.17 or higher allows the uC to
+ * be reset

[PATCH v2 36/51] IB/qib: Add qib_sdma.c

2009-12-03 Thread Ralph Campbell
creates the qib_sdma.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_sdma.c | 1037 ++
 1 files changed, 1037 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sdma.c

diff --git a/drivers/infiniband/hw/qib/qib_sdma.c 
b/drivers/infiniband/hw/qib/qib_sdma.c
new file mode 100644
index 000..4b58f26
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sdma.c
@@ -0,0 +1,1037 @@
+/*
+ * Copyright (c) 2007, 2008, 2009 QLogic Corporation. 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/spinlock.h
+#include linux/netdevice.h
+
+#include qib.h
+#include qib_common.h
+
+/* default pio off, sdma on */
+static ushort sdma_descq_cnt = 256;
+module_param_named(sdma_descq_cnt, sdma_descq_cnt, ushort, S_IRUGO);
+MODULE_PARM_DESC(sdma_descq_cnt, Number of SDMA descq entries);
+
+/*
+ * Bits defined in the send DMA descriptor.
+ */
+#define SDMA_DESC_LAST  (1ULL  11)
+#define SDMA_DESC_FIRST (1ULL  12)
+#define SDMA_DESC_DMA_HEAD  (1ULL  13)
+#define SDMA_DESC_USE_LARGE_BUF (1ULL  14)
+#define SDMA_DESC_INTR  (1ULL  15)
+#define SDMA_DESC_COUNT_LSB 16
+#define SDMA_DESC_GEN_LSB   30
+
+char *qib_sdma_state_names[] = {
+   [qib_sdma_state_s00_hw_down]  = s00_HwDown,
+   [qib_sdma_state_s10_hw_start_up_wait] = s10_HwStartUpWait,
+   [qib_sdma_state_s20_idle] = s20_Idle,
+   [qib_sdma_state_s30_sw_clean_up_wait] = s30_SwCleanUpWait,
+   [qib_sdma_state_s40_hw_clean_up_wait] = s40_HwCleanUpWait,
+   [qib_sdma_state_s50_hw_halt_wait] = s50_HwHaltWait,
+   [qib_sdma_state_s99_running]  = s99_Running,
+};
+
+char *qib_sdma_event_names[] = {
+   [qib_sdma_event_e00_go_hw_down]   = e00_GoHwDown,
+   [qib_sdma_event_e10_go_hw_start]  = e10_GoHwStart,
+   [qib_sdma_event_e20_hw_started]   = e20_HwStarted,
+   [qib_sdma_event_e30_go_running]   = e30_GoRunning,
+   [qib_sdma_event_e40_sw_cleaned]   = e40_SwCleaned,
+   [qib_sdma_event_e50_hw_cleaned]   = e50_HwCleaned,
+   [qib_sdma_event_e60_hw_halted]= e60_HwHalted,
+   [qib_sdma_event_e70_go_idle]  = e70_GoIdle,
+   [qib_sdma_event_e7220_err_halted] = e7220_ErrHalted,
+   [qib_sdma_event_e7322_err_halted] = e7322_ErrHalted,
+   [qib_sdma_event_e90_timer_tick]   = e90_TimerTick,
+};
+
+/* declare all statics here rather than keep sorting */
+static int alloc_sdma(struct qib_pportdata *);
+static void sdma_complete(struct kref *);
+static void sdma_finalput(struct qib_sdma_state *);
+static void sdma_get(struct qib_sdma_state *);
+static void sdma_put(struct qib_sdma_state *);
+static void sdma_set_state(struct qib_pportdata *, enum qib_sdma_states);
+static void sdma_start_sw_clean_up(struct qib_pportdata *);
+static void sdma_sw_clean_up_task(unsigned long);
+static void unmap_desc(struct qib_pportdata *, unsigned);
+
+static void sdma_get(struct qib_sdma_state *ss)
+{
+   kref_get(ss-kref);
+}
+
+static void sdma_complete(struct kref *kref)
+{
+   struct qib_sdma_state *ss =
+   container_of(kref, struct qib_sdma_state, kref);
+
+   complete(ss-comp);
+}
+
+static void sdma_put(struct qib_sdma_state *ss)
+{
+   kref_put(ss-kref, sdma_complete);
+}
+
+static void sdma_finalput(struct qib_sdma_state *ss)
+{
+   sdma_put(ss);
+   wait_for_completion(ss-comp);
+}
+
+/*
+ * Complete all the sdma requests on the active list, in the correct
+ * order, and with appropriate processing.   Called when cleaning up
+ * after sdma shutdown

[PATCH v2 37/51] IB/qib: Add qib_srq.c

2009-12-03 Thread Ralph Campbell
creates the qib_srq.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_srq.c |  374 +++
 1 files changed, 374 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_srq.c

diff --git a/drivers/infiniband/hw/qib/qib_srq.c 
b/drivers/infiniband/hw/qib/qib_srq.c
new file mode 100644
index 000..d79ae33
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_srq.c
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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/err.h
+#include linux/vmalloc.h
+
+#include qib_verbs.h
+
+/**
+ * qib_post_srq_receive - post a receive on a shared receive queue
+ * @ibsrq: the SRQ to post the receive on
+ * @wr: the list of work requests to post
+ * @bad_wr: A pointer to the first WR to cause a problem is put here
+ *
+ * This may be called from interrupt context.
+ */
+int qib_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
+struct ib_recv_wr **bad_wr)
+{
+   struct qib_srq *srq = to_isrq(ibsrq);
+   struct qib_rwq *wq;
+   unsigned long flags;
+   int ret;
+
+   for (; wr; wr = wr-next) {
+   struct qib_rwqe *wqe;
+   u32 next;
+   int i;
+
+   if ((unsigned) wr-num_sge  srq-rq.max_sge) {
+   *bad_wr = wr;
+   ret = -EINVAL;
+   goto bail;
+   }
+
+   spin_lock_irqsave(srq-rq.lock, flags);
+   wq = srq-rq.wq;
+   next = wq-head + 1;
+   if (next = srq-rq.size)
+   next = 0;
+   if (next == wq-tail) {
+   spin_unlock_irqrestore(srq-rq.lock, flags);
+   *bad_wr = wr;
+   ret = -ENOMEM;
+   goto bail;
+   }
+
+   wqe = get_rwqe_ptr(srq-rq, wq-head);
+   wqe-wr_id = wr-wr_id;
+   wqe-num_sge = wr-num_sge;
+   for (i = 0; i  wr-num_sge; i++)
+   wqe-sg_list[i] = wr-sg_list[i];
+   /* Make sure queue entry is written before the head index. */
+   smp_wmb();
+   wq-head = next;
+   spin_unlock_irqrestore(srq-rq.lock, flags);
+   }
+   ret = 0;
+
+bail:
+   return ret;
+}
+
+/**
+ * qib_create_srq - create a shared receive queue
+ * @ibpd: the protection domain of the SRQ to create
+ * @srq_init_attr: the attributes of the SRQ
+ * @udata: data from libibverbs when creating a user SRQ
+ */
+struct ib_srq *qib_create_srq(struct ib_pd *ibpd,
+ struct ib_srq_init_attr *srq_init_attr,
+ struct ib_udata *udata)
+{
+   struct qib_ibdev *dev = to_idev(ibpd-device);
+   struct qib_srq *srq;
+   u32 sz;
+   struct ib_srq *ret;
+
+   if (srq_init_attr-attr.max_sge == 0 ||
+   srq_init_attr-attr.max_sge  ib_qib_max_srq_sges ||
+   srq_init_attr-attr.max_wr == 0 ||
+   srq_init_attr-attr.max_wr  ib_qib_max_srq_wrs) {
+   ret = ERR_PTR(-EINVAL);
+   goto done;
+   }
+
+   srq = kmalloc(sizeof(*srq), GFP_KERNEL);
+   if (!srq) {
+   ret = ERR_PTR(-ENOMEM);
+   goto done;
+   }
+
+   /*
+* Need to use vmalloc() if we want to support large #s of entries.
+*/
+   srq-rq.size = srq_init_attr

[PATCH v2 38/51] IB/qib: Add qib_sysfs.c

2009-12-03 Thread Ralph Campbell
creates the qib_sysfs.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_sysfs.c |  736 +
 1 files changed, 736 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sysfs.c

diff --git a/drivers/infiniband/hw/qib/qib_sysfs.c 
b/drivers/infiniband/hw/qib/qib_sysfs.c
new file mode 100644
index 000..747005a
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sysfs.c
@@ -0,0 +1,736 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2006 PathScale, Inc. 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/ctype.h
+
+#include qib.h
+
+/**
+ * qib_parse_ushort - parse an unsigned short value in an arbitrary base
+ * @str: the string containing the number
+ * @valp: where to put the result
+ *
+ * Returns the number of bytes consumed, or negative value on error.
+ */
+static int qib_parse_ushort(const char *str, unsigned short *valp)
+{
+   unsigned long val;
+   char *end;
+   int ret;
+
+   if (!isdigit(str[0])) {
+   ret = -EINVAL;
+   goto bail;
+   }
+
+   val = simple_strtoul(str, end, 0);
+
+   if (val  0x) {
+   ret = -EINVAL;
+   goto bail;
+   }
+
+   *valp = val;
+
+   ret = end + 1 - str;
+   if (ret == 0)
+   ret = -EINVAL;
+
+bail:
+   return ret;
+}
+
+/* start of per-port functions */
+/*
+ * Get/Set heartbeat enable. OR of 1=enabled, 2=auto
+ */
+static ssize_t show_hrtbt_enb(struct qib_pportdata *ppd, char *buf)
+{
+   struct qib_devdata *dd = ppd-dd;
+   int ret;
+
+   ret = dd-f_get_ib_cfg(ppd, QIB_IB_CFG_HRTBT);
+   ret = scnprintf(buf, PAGE_SIZE, %d\n, ret);
+   return ret;
+}
+
+static ssize_t store_hrtbt_enb(struct qib_pportdata *ppd, const char *buf,
+  size_t count)
+{
+   struct qib_devdata *dd = ppd-dd;
+   int ret;
+   u16 val;
+
+   ret = qib_parse_ushort(buf, val);
+
+   /*
+* Set the intentional heartbeat enable per either of
+* Enable and Auto, as these are normally set together.
+* This bit is consulted when leaving loopback mode,
+* because entering loopback mode overrides it and automatically
+* disables heartbeat.
+*/
+   if (ret = 0)
+   ret = dd-f_set_ib_cfg(ppd, QIB_IB_CFG_HRTBT, val);
+   if (ret  0)
+   qib_dev_err(dd, attempt to set invalid Heartbeat enable\n);
+   return ret  0 ? ret : count;
+}
+
+static ssize_t store_loopback(struct qib_pportdata *ppd, const char *buf,
+ size_t count)
+{
+   struct qib_devdata *dd = ppd-dd;
+   int ret = count, r;
+
+   r = dd-f_set_ib_loopback(ppd, buf);
+   if (r  0)
+   ret = r;
+
+   return ret;
+}
+
+static ssize_t store_led_override(struct qib_pportdata *ppd, const char *buf,
+ size_t count)
+{
+   struct qib_devdata *dd = ppd-dd;
+   int ret;
+   u16 val;
+
+   ret = qib_parse_ushort(buf, val);
+   if (ret  0)
+   qib_set_led_override(ppd, val);
+   else
+   qib_dev_err(dd, attempt to set invalid LED override\n);
+   return ret  0 ? ret : count;
+}
+
+static ssize_t show_qsfp(struct qib_pportdata *ppd, char *buf)
+{
+   ssize_t ret;
+
+   ret = qib_qsfp_dump(ppd, buf, PAGE_SIZE);
+   return ret;
+}
+
+static ssize_t show_status(struct qib_pportdata *ppd, char *buf)
+{
+   ssize_t ret

[PATCH v2 40/51] IB/qib: Add qib_tx.c

2009-12-03 Thread Ralph Campbell
creates the qib_tx.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_tx.c |  585 
 1 files changed, 585 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_tx.c

diff --git a/drivers/infiniband/hw/qib/qib_tx.c 
b/drivers/infiniband/hw/qib/qib_tx.c
new file mode 100644
index 000..7d77f29
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_tx.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. 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/spinlock.h
+#include linux/pci.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/netdevice.h
+#include linux/vmalloc.h
+
+#include qib.h
+
+static unsigned qib_hol_timeout_ms = 3000;
+module_param_named(hol_timeout_ms, qib_hol_timeout_ms, uint, S_IRUGO);
+MODULE_PARM_DESC(hol_timeout_ms,
+duration of user app suspension after link failure);
+
+unsigned qib_sdma_fetch_arb = 1;
+module_param_named(fetch_arb, qib_sdma_fetch_arb, uint, S_IRUGO);
+MODULE_PARM_DESC(fetch_arb, IBA7220: change SDMA descriptor arbitration);
+
+/**
+ * qib_disarm_piobufs - cancel a range of PIO buffers
+ * @dd: the qlogic_ib device
+ * @first: the first PIO buffer to cancel
+ * @cnt: the number of PIO buffers to cancel
+ *
+ * Cancel a range of PIO buffers. Used at user process close,
+ * in case it died while writing to a PIO buffer.
+ */
+void qib_disarm_piobufs(struct qib_devdata *dd, unsigned first, unsigned cnt)
+{
+   unsigned long flags;
+   unsigned i;
+   unsigned last;
+
+   qib_cdbg(ERRPKT, disarm %u PIObufs first=%u\n, cnt, first);
+   last = first + cnt;
+   spin_lock_irqsave(dd-pioavail_lock, flags);
+   for (i = first; i  last; i++) {
+   __clear_bit(i, dd-pio_need_disarm);
+   dd-f_sendctrl(dd-pport, QIB_SENDCTRL_DISARM_BUF(i));
+   }
+   spin_unlock_irqrestore(dd-pioavail_lock, flags);
+}
+
+/*
+ * This is called by a user process when it sees the DISARM_BUFS event
+ * bit is set.
+ */
+int qib_disarm_piobufs_ifneeded(struct qib_ctxtdata *rcd)
+{
+   struct qib_devdata *dd = rcd-dd;
+   unsigned i;
+   unsigned last;
+   unsigned n = 0;
+
+   last = rcd-pio_base + rcd-piocnt;
+   /*
+* Don't need uctxt_lock here, since user has called in to us.
+* Clear at start in case more interrupts set bits while we
+* are disarming
+*/
+   if (rcd-user_event_mask) {
+   /*
+* subctxt_cnt is 0 if not shared, so do base
+* separately, first, then remaining subctxt, if any
+*/
+   clear_bit(_QIB_EVENT_DISARM_BUFS_BIT, rcd-user_event_mask[0]);
+   for (i = 1; i  rcd-subctxt_cnt; i++)
+   clear_bit(_QIB_EVENT_DISARM_BUFS_BIT,
+ rcd-user_event_mask[i]);
+   }
+   spin_lock_irq(dd-pioavail_lock);
+   for (i = rcd-pio_base; i  last; i++) {
+   if (__test_and_clear_bit(i, dd-pio_need_disarm)) {
+   n++;
+   dd-f_sendctrl(rcd-ppd, QIB_SENDCTRL_DISARM_BUF(i));
+   }
+   }
+   spin_unlock_irq(dd-pioavail_lock);
+   qib_cdbg(ERRPKT, Ctxt%u, User disarm (%u bufs (%u-%u)) done\n,
+   rcd-ctxt, n, rcd-pio_base, last);
+   return 0;
+}
+
+static struct qib_pportdata *is_sdma_buf(struct qib_devdata *dd, unsigned i)
+{
+   struct qib_pportdata *ppd;
+   unsigned pidx;
+
+   for (pidx = 0; pidx  dd-num_pports; pidx

[PATCH v2 35/51] IB/qib: Add qib_sd7220_img.c

2009-12-03 Thread Ralph Campbell
creates the qib_sd7220_img.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_sd7220_img.c | 1081 
 1 files changed, 1081 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sd7220_img.c

diff --git a/drivers/infiniband/hw/qib/qib_sd7220_img.c 
b/drivers/infiniband/hw/qib/qib_sd7220_img.c
new file mode 100644
index 000..a1118fb
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sd7220_img.c
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (c) 2007, 2008 QLogic Corporation. 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.
+ */
+
+/*
+ * This file contains the memory image from the vendor, to be copied into
+ * the IB SERDES of the IBA7220 during initialization.
+ * The file also includes the two functions which use this image.
+ */
+#include linux/pci.h
+#include linux/delay.h
+
+#include qib.h
+#include qib_7220.h
+
+static unsigned char qib_sd7220_ib_img[] = {
+/**/0x02, 0x0A, 0x29, 0x02, 0x0A, 0x87, 0xE5, 0xE6,
+   0x30, 0xE6, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F,
+/*0010*/0x00, 0xE5, 0xE2, 0x30, 0xE4, 0x04, 0x7E, 0x01,
+   0x80, 0x02, 0x7E, 0x00, 0xEE, 0x5F, 0x60, 0x08,
+/*0020*/0x53, 0xF9, 0xF7, 0xE4, 0xF5, 0xFE, 0x80, 0x08,
+   0x7F, 0x0A, 0x12, 0x17, 0x31, 0x12, 0x0E, 0xA2,
+/*0030*/0x75, 0xFC, 0x08, 0xE4, 0xF5, 0xFD, 0xE5, 0xE7,
+   0x20, 0xE7, 0x03, 0x43, 0xF9, 0x08, 0x22, 0x00,
+/*0040*/0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x75,
+   0x51, 0x01, 0xE4, 0xF5, 0x52, 0xF5, 0x53, 0xF5,
+/*0050*/0x52, 0xF5, 0x7E, 0x7F, 0x04, 0x02, 0x04, 0x38,
+   0xC2, 0x36, 0x05, 0x52, 0xE5, 0x52, 0xD3, 0x94,
+/*0060*/0x0C, 0x40, 0x05, 0x75, 0x52, 0x01, 0xD2, 0x36,
+   0x90, 0x07, 0x0C, 0x74, 0x07, 0xF0, 0xA3, 0x74,
+/*0070*/0xFF, 0xF0, 0xE4, 0xF5, 0x0C, 0xA3, 0xF0, 0x90,
+   0x07, 0x14, 0xF0, 0xA3, 0xF0, 0x75, 0x0B, 0x20,
+/*0080*/0xF5, 0x09, 0xE4, 0xF5, 0x08, 0xE5, 0x08, 0xD3,
+   0x94, 0x30, 0x40, 0x03, 0x02, 0x04, 0x04, 0x12,
+/*0090*/0x00, 0x06, 0x15, 0x0B, 0xE5, 0x08, 0x70, 0x04,
+   0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x09,
+/*00A0*/0x70, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00,
+   0xEE, 0x5F, 0x60, 0x05, 0x12, 0x18, 0x71, 0xD2,
+/*00B0*/0x35, 0x53, 0xE1, 0xF7, 0xE5, 0x08, 0x45, 0x09,
+   0xFF, 0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24,
+/*00C0*/0x83, 0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83,
+   0xEF, 0xF0, 0x85, 0xE2, 0x20, 0xE5, 0x52, 0xD3,
+/*00D0*/0x94, 0x01, 0x40, 0x0D, 0x12, 0x19, 0xF3, 0xE0,
+   0x54, 0xA0, 0x64, 0x40, 0x70, 0x03, 0x02, 0x03,
+/*00E0*/0xFB, 0x53, 0xF9, 0xF8, 0x90, 0x94, 0x70, 0xE4,
+   0xF0, 0xE0, 0xF5, 0x10, 0xAF, 0x09, 0x12, 0x1E,
+/*00F0*/0xB3, 0xAF, 0x08, 0xEF, 0x44, 0x08, 0xF5, 0x82,
+   0x75, 0x83, 0x80, 0xE0, 0xF5, 0x29, 0xEF, 0x44,
+/*0100*/0x07, 0x12, 0x1A, 0x3C, 0xF5, 0x22, 0x54, 0x40,
+   0xD3, 0x94, 0x00, 0x40, 0x1E, 0xE5, 0x29, 0x54,
+/*0110*/0xF0, 0x70, 0x21, 0x12, 0x19, 0xF3, 0xE0, 0x44,
+   0x80, 0xF0, 0xE5, 0x22, 0x54, 0x30, 0x65, 0x08,
+/*0120*/0x70, 0x09, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xBF,
+   0xF0, 0x80, 0x09, 0x12, 0x19, 0xF3, 0x74, 0x40,
+/*0130*/0xF0, 0x02, 0x03, 0xFB, 0x12, 0x1A, 0x12, 0x75,
+   0x83, 0xAE, 0x74, 0xFF, 0xF0, 0xAF, 0x08, 0x7E,
+/*0140*/0x00, 0xEF, 0x44, 0x07, 0xF5, 0x82, 0xE0, 0xFD,
+   0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24, 0x81,
+/*0150*/0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83, 0xED,
+   0xF0, 0x90, 0x07, 0x0E, 0xE0, 0x04, 0xF0, 0xEF,
+/*0160*/0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0x98, 0xE0,
+   0xF5, 0x28, 0x12, 0x1A, 0x23, 0x40, 0x0C, 0x12,
+/*0170*/0x19, 0xF3, 0xE0, 0x44, 0x01, 0x12, 0x1A, 0x32,
+   0x02

[PATCH v2 42/51] IB/qib: Add qib_ud.c

2009-12-03 Thread Ralph Campbell
creates the qib_ud.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_ud.c |  607 
 1 files changed, 607 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_ud.c

diff --git a/drivers/infiniband/hw/qib/qib_ud.c 
b/drivers/infiniband/hw/qib/qib_ud.c
new file mode 100644
index 000..c838cda
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_ud.c
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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 rdma/ib_smi.h
+
+#include qib.h
+#include qib_mad.h
+
+/**
+ * qib_ud_loopback - handle send on loopback QPs
+ * @sqp: the sending QP
+ * @swqe: the send work request
+ *
+ * This is called from qib_make_ud_req() to forward a WQE addressed
+ * to the same HCA.
+ * Note that the receive interrupt handler may be calling qib_ud_rcv()
+ * while this is being called.
+ */
+static void qib_ud_loopback(struct qib_qp *sqp, struct qib_swqe *swqe)
+{
+   struct qib_ibport *ibp = to_iport(sqp-ibqp.device, sqp-port_num);
+   struct qib_pportdata *ppd;
+   struct qib_qp *qp;
+   struct ib_ah_attr *ah_attr;
+   unsigned long flags;
+   struct qib_sge_state ssge;
+   struct qib_sge *sge;
+   struct ib_wc wc;
+   u32 length;
+
+   qp = qib_lookup_qpn(ibp, swqe-wr.wr.ud.remote_qpn);
+   if (!qp) {
+   ibp-n_pkt_drops++;
+   return;
+   }
+   if (qp-ibqp.qp_type != sqp-ibqp.qp_type ||
+   !(ib_qib_state_ops[qp-state]  QIB_PROCESS_RECV_OK)) {
+   ibp-n_pkt_drops++;
+   goto drop;
+   }
+
+   ah_attr = to_iah(swqe-wr.wr.ud.ah)-attr;
+   ppd = ppd_from_ibp(ibp);
+
+   if (qp-ibqp.qp_num  1) {
+   u16 pkey1;
+   u16 pkey2;
+   u16 lid;
+
+   pkey1 = qib_get_pkey(ibp, sqp-s_pkey_index);
+   pkey2 = qib_get_pkey(ibp, qp-s_pkey_index);
+   if (unlikely(!qib_pkey_ok(pkey1, pkey2))) {
+   lid = ppd-lid | (ah_attr-src_path_bits 
+ ((1  ppd-lmc) - 1));
+   qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, pkey1,
+ ah_attr-sl,
+ sqp-ibqp.qp_num, qp-ibqp.qp_num,
+ cpu_to_be16(lid),
+ cpu_to_be16(ah_attr-dlid));
+   goto drop;
+   }
+   }
+
+   /*
+* Check that the qkey matches (except for QP0, see 9.6.1.4.1).
+* Qkeys with the high order bit set mean use the
+* qkey from the QP context instead of the WR (see 10.2.5).
+*/
+   if (qp-ibqp.qp_num) {
+   u32 qkey;
+
+   qkey = (int)swqe-wr.wr.ud.remote_qkey  0 ?
+   sqp-qkey : swqe-wr.wr.ud.remote_qkey;
+   if (unlikely(qkey != qp-qkey)) {
+   u16 lid;
+
+   lid = ppd-lid | (ah_attr-src_path_bits 
+ ((1  ppd-lmc) - 1));
+   qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey,
+ ah_attr-sl,
+ sqp-ibqp.qp_num, qp-ibqp.qp_num,
+ cpu_to_be16(lid),
+ cpu_to_be16(ah_attr-dlid));
+   goto drop

[PATCH v2 43/51] IB/qib: Add qib_user_pages.c

2009-12-03 Thread Ralph Campbell
creates the qib_user_pages.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_user_pages.c |  163 
 1 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_user_pages.c

diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c 
b/drivers/infiniband/hw/qib/qib_user_pages.c
new file mode 100644
index 000..a0406a2
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_user_pages.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/mm.h
+#include linux/device.h
+
+#include qib.h
+
+static void __qib_release_user_pages(struct page **p, size_t num_pages,
+int dirty)
+{
+   size_t i;
+
+   for (i = 0; i  num_pages; i++) {
+   qib_cdbg(MM, %lu/%lu put_page %p\n, (unsigned long) i,
+(unsigned long) num_pages, p[i]);
+   if (dirty)
+   set_page_dirty_lock(p[i]);
+   put_page(p[i]);
+   }
+}
+
+/*
+ * Call with current-mm-mmap_sem held.
+ */
+static int __get_user_pages(unsigned long start_page, size_t num_pages,
+   struct page **p, struct vm_area_struct **vma)
+{
+   unsigned long lock_limit;
+   size_t got;
+   int ret;
+
+   lock_limit = current-signal-rlim[RLIMIT_MEMLOCK].rlim_cur 
+   PAGE_SHIFT;
+
+   if (num_pages  lock_limit) {
+   ret = -ENOMEM;
+   goto bail;
+   }
+
+   qib_cdbg(VERBOSE, pin %lx pages from vaddr %lx\n,
+(unsigned long) num_pages, start_page);
+
+   for (got = 0; got  num_pages; got += ret) {
+   ret = get_user_pages(current, current-mm,
+start_page + got * PAGE_SIZE,
+num_pages - got, 1, 1,
+p + got, vma);
+   if (ret  0)
+   goto bail_release;
+   }
+
+   current-mm-locked_vm += num_pages;
+
+   ret = 0;
+   goto bail;
+
+bail_release:
+   __qib_release_user_pages(p, got, 0);
+bail:
+   return ret;
+}
+
+/**
+ * qib_map_page - a safety wrapper around pci_map_page()
+ *
+ * A dma_addr of all 0's is interpreted by the chip as disabled.
+ * Unfortunately, it can also be a valid dma_addr returned on some
+ * architectures.
+ *
+ * The powerpc iommu assigns dma_addrs in ascending order, so we don't
+ * have to bother with retries or mapping a dummy page to insure we
+ * don't just get the same mapping again.
+ *
+ * I'm sure we won't be so lucky with other iommu's, so FIXME.
+ */
+dma_addr_t qib_map_page(struct pci_dev *hwdev, struct page *page,
+   unsigned long offset, size_t size, int direction)
+{
+   dma_addr_t phys;
+
+   phys = pci_map_page(hwdev, page, offset, size, direction);
+
+   if (phys == 0) {
+   pci_unmap_page(hwdev, phys, size, direction);
+   phys = pci_map_page(hwdev, page, offset, size, direction);
+   /*
+* FIXME: If we get 0 again, we should keep this page,
+* map another, then free the 0 page.
+*/
+   }
+
+   return phys;
+}
+
+/**
+ * qib_get_user_pages - lock user pages into memory
+ * @start_page: the start page
+ * @num_pages: the number of pages
+ * @p: the output page structures
+ *
+ * This function takes

[PATCH v2 45/51] IB/qib: Add qib_user_sdma.h

2009-12-03 Thread Ralph Campbell
creates the qib_user_sdma.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_user_sdma.h |   52 +
 1 files changed, 52 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_user_sdma.h

diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.h 
b/drivers/infiniband/hw/qib/qib_user_sdma.h
new file mode 100644
index 000..ce8cbaf
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_user_sdma.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 2008 QLogic Corporation. 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/device.h
+
+struct qib_user_sdma_queue;
+
+struct qib_user_sdma_queue *
+qib_user_sdma_queue_create(struct device *dev, int unit, int port, int sport);
+void qib_user_sdma_queue_destroy(struct qib_user_sdma_queue *pq);
+
+int qib_user_sdma_writev(struct qib_ctxtdata *pd,
+struct qib_user_sdma_queue *pq,
+const struct iovec *iov,
+unsigned long dim);
+
+int qib_user_sdma_make_progress(struct qib_pportdata *ppd,
+   struct qib_user_sdma_queue *pq);
+
+void qib_user_sdma_queue_drain(struct qib_pportdata *ppd,
+  struct qib_user_sdma_queue *pq);
+
+u32 qib_user_sdma_complete_counter(const struct qib_user_sdma_queue *pq);
+u32 qib_user_sdma_inflight_counter(struct qib_user_sdma_queue *pq);

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 47/51] IB/qib: Add qib_verbs.h

2009-12-03 Thread Ralph Campbell
creates the qib_verbs.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_verbs.h | 1086 +
 1 files changed, 1086 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_verbs.h

diff --git a/drivers/infiniband/hw/qib/qib_verbs.h 
b/drivers/infiniband/hw/qib/qib_verbs.h
new file mode 100644
index 000..20c8ec1
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_verbs.h
@@ -0,0 +1,1086 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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.
+ */
+
+#ifndef QIB_VERBS_H
+#define QIB_VERBS_H
+
+#include linux/types.h
+#include linux/spinlock.h
+#include linux/kernel.h
+#include linux/interrupt.h
+#include linux/kref.h
+#include linux/workqueue.h
+#include rdma/ib_pack.h
+#include rdma/ib_user_verbs.h
+
+struct qib_ctxtdata;
+struct qib_pportdata;
+struct qib_devdata;
+struct qib_verbs_txreq;
+
+#define QIB_MAX_RDMA_ATOMIC 16
+#define QIB_GUIDS_PER_PORT 5
+
+#define QPN_MAX (1  24)
+#define QPNMAP_ENTRIES  (QPN_MAX / PAGE_SIZE / BITS_PER_BYTE)
+
+/*
+ * Increment this value if any changes that break userspace ABI
+ * compatibility are made.
+ */
+#define QIB_UVERBS_ABI_VERSION   2
+
+/*
+ * Define an ib_cq_notify value that is not valid so we know when CQ
+ * notifications are armed.
+ */
+#define IB_CQ_NONE  (IB_CQ_NEXT_COMP + 1)
+
+#define IB_SEQ_NAK (3  29)
+
+/* AETH NAK opcode values */
+#define IB_RNR_NAK  0x20
+#define IB_NAK_PSN_ERROR0x60
+#define IB_NAK_INVALID_REQUEST  0x61
+#define IB_NAK_REMOTE_ACCESS_ERROR  0x62
+#define IB_NAK_REMOTE_OPERATIONAL_ERROR 0x63
+#define IB_NAK_INVALID_RD_REQUEST   0x64
+
+/* Flags for checking QP state (see ib_qib_state_ops[]) */
+#define QIB_POST_SEND_OK0x01
+#define QIB_POST_RECV_OK0x02
+#define QIB_PROCESS_RECV_OK 0x04
+#define QIB_PROCESS_SEND_OK 0x08
+#define QIB_PROCESS_NEXT_SEND_OK0x10
+#define QIB_FLUSH_SEND 0x20
+#define QIB_FLUSH_RECV 0x40
+#define QIB_PROCESS_OR_FLUSH_SEND \
+   (QIB_PROCESS_SEND_OK | QIB_FLUSH_SEND)
+
+/* IB Performance Manager status values */
+#define IB_PMA_SAMPLE_STATUS_DONE   0x00
+#define IB_PMA_SAMPLE_STATUS_STARTED0x01
+#define IB_PMA_SAMPLE_STATUS_RUNNING0x02
+
+/* Mandatory IB performance counter select values. */
+#define IB_PMA_PORT_XMIT_DATA   cpu_to_be16(0x0001)
+#define IB_PMA_PORT_RCV_DATAcpu_to_be16(0x0002)
+#define IB_PMA_PORT_XMIT_PKTS   cpu_to_be16(0x0003)
+#define IB_PMA_PORT_RCV_PKTScpu_to_be16(0x0004)
+#define IB_PMA_PORT_XMIT_WAIT   cpu_to_be16(0x0005)
+
+#define QIB_VENDOR_IPG cpu_to_be16(0xFFA0)
+
+#define IB_BTH_REQ_ACK (1  31)
+#define IB_BTH_SOLICITED   (1  23)
+#define IB_BTH_MIG_REQ (1  22)
+
+/* XXX Should be defined in ib_verbs.h enum ib_port_cap_flags */
+#define IB_PORT_OTHER_LOCAL_CHANGES_SUP (1  26)
+
+#define IB_GRH_VERSION 6
+#define IB_GRH_VERSION_MASK0xF
+#define IB_GRH_VERSION_SHIFT   28
+#define IB_GRH_TCLASS_MASK 0xFF
+#define IB_GRH_TCLASS_SHIFT20
+#define IB_GRH_FLOW_MASK   0xF
+#define IB_GRH_FLOW_SHIFT  0
+#define IB_GRH_NEXT_HDR0x1B
+
+#define IB_DEFAULT_GID_PREFIX  cpu_to_be64(0xfe80ULL)
+
+/* Values for set/get portinfo VLCap OperationalVLs */
+#define IB_VL_VL0   1
+#define IB_VL_VL0_1 2
+#define IB_VL_VL0_3 3

[PATCH v2 50/51] IB/qib: Add qib_wc_x86_64.c

2009-12-03 Thread Ralph Campbell
creates the qib_wc_x86_64.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_wc_x86_64.c |  187 +
 1 files changed, 187 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_wc_x86_64.c

diff --git a/drivers/infiniband/hw/qib/qib_wc_x86_64.c 
b/drivers/infiniband/hw/qib/qib_wc_x86_64.c
new file mode 100644
index 000..594c198
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_wc_x86_64.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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.
+ */
+
+/*
+ * This file is conditionally built on x86_64 only.  Otherwise weak symbol
+ * versions of the functions exported from here are used.
+ */
+
+#include linux/pci.h
+#include asm/mtrr.h
+#include asm/processor.h
+
+#include qib.h
+
+/**
+ * qib_enable_wc - enable write combining for MMIO writes to the device
+ * @dd: qlogic_ib device
+ *
+ * This routine is x86_64-specific; it twiddles the CPU's MTRRs to enable
+ * write combining.
+ */
+int qib_enable_wc(struct qib_devdata *dd)
+{
+   int ret = 0;
+   u64 pioaddr, piolen;
+   unsigned bits;
+   const unsigned long addr = pci_resource_start(dd-pcidev, 0);
+   const size_t len = pci_resource_len(dd-pcidev, 0);
+
+   /*
+* Set the PIO buffers to be WCCOMB, so we get HT bursts to the
+* chip.  Linux (possibly the hardware) requires it to be on a power
+* of 2 address matching the length (which has to be a power of 2).
+* For rev1, that means the base address, for rev2, it will be just
+* the PIO buffers themselves.
+* For chips with two sets of buffers, the calculations are
+* somewhat more complicated; we need to sum, and the piobufbase
+* register has both offsets, 2K in low 32 bits, 4K in high 32 bits.
+* The buffers are still packed, so a single range covers both.
+*/
+   if (dd-piobcnt2k  dd-piobcnt4k) {
+   /* 2 sizes for chip */
+   unsigned long pio2kbase, pio4kbase;
+   pio2kbase = dd-piobufbase  0xUL;
+   pio4kbase = (dd-piobufbase  32)  0xUL;
+   if (pio2kbase  pio4kbase) {
+   /* all current chips */
+   pioaddr = addr + pio2kbase;
+   piolen = pio4kbase - pio2kbase +
+   dd-piobcnt4k * dd-align4k;
+   } else {
+   pioaddr = addr + pio4kbase;
+   piolen = pio2kbase - pio4kbase +
+   dd-piobcnt2k * dd-palign;
+   }
+   } else {  /* single buffer size (2K, currently) */
+   pioaddr = addr + dd-piobufbase;
+   piolen = dd-piobcnt2k * dd-palign +
+   dd-piobcnt4k * dd-align4k;
+   }
+
+   for (bits = 0; !(piolen  (1ULL  bits)); bits++)
+   /* do nothing */ ;
+
+   if (piolen != (1ULL  bits)) {
+   piolen = bits;
+   while (piolen = 1)
+   bits++;
+   piolen = 1ULL  (bits + 1);
+   }
+   if (pioaddr  (piolen - 1)) {
+   u64 atmp;
+   qib_dbg(pioaddr %llx not on right boundary for size 
+ %llx, fixing\n,
+ (unsigned long long) pioaddr,
+ (unsigned long long) piolen);
+   atmp = pioaddr  ~(piolen - 1

[PATCH v2 51/51] IB/qib: Hooks for adding the QIB driver into the framework

2009-12-03 Thread Ralph Campbell
Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/Kconfig  |1 +
 drivers/infiniband/Makefile |1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index dd0db67..c80f973 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -42,6 +42,7 @@ config INFINIBAND_ADDR_TRANS
 
 source drivers/infiniband/hw/mthca/Kconfig
 source drivers/infiniband/hw/ipath/Kconfig
+source drivers/infiniband/hw/qib/Kconfig
 source drivers/infiniband/hw/ehca/Kconfig
 source drivers/infiniband/hw/amso1100/Kconfig
 source drivers/infiniband/hw/cxgb3/Kconfig
diff --git a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile
index ed35e44..27b66b1 100644
--- a/drivers/infiniband/Makefile
+++ b/drivers/infiniband/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_INFINIBAND)   += core/
 obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/
 obj-$(CONFIG_INFINIBAND_IPATH) += hw/ipath/
+obj-$(CONFIG_INFINIBAND_QIB)   += hw/qib/
 obj-$(CONFIG_INFINIBAND_EHCA)  += hw/ehca/
 obj-$(CONFIG_INFINIBAND_AMSO1100)  += hw/amso1100/
 obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 07/53] IB/qib: Add qib_7322_regs.h

2009-11-24 Thread Ralph Campbell
On Mon, 2009-11-23 at 20:04 -0800, Roland Dreier wrote:
 Do we really need 9000+ lines of these defines, most of which are
 unused?  Is this automatically generated or something?
 
  - R.

The file is automatically generated from the HW description
files we use internally. It is obviously easier for us to
leave it as is but if you feel strongly, we can filter the
output to only contain the ones we use.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 07/53] IB/qib: Add qib_7322_regs.h

2009-11-24 Thread Ralph Campbell
On Tue, 2009-11-24 at 14:29 -0800, Roland Dreier wrote:
  The file is automatically generated from the HW description
   files we use internally. It is obviously easier for us to
   leave it as is but if you feel strongly, we can filter the
   output to only contain the ones we use.
 
 This one file is bigger than the whole amso1100 driver.  Which seems
 pretty excessive to me.  I mean, 9734 lines of register defines?!

OK. It looks like I can shrink the 3 register header files by about 50%.
There really are a lot of registers and most of them are used.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/53] IB/qib: Add Makefile

2009-11-19 Thread Ralph Campbell
This creates the Makefile file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/Makefile |   46 
 1 files changed, 46 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/Makefile

diff --git a/drivers/infiniband/hw/qib/Makefile 
b/drivers/infiniband/hw/qib/Makefile
new file mode 100644
index 000..5dc5134
--- /dev/null
+++ b/drivers/infiniband/hw/qib/Makefile
@@ -0,0 +1,46 @@
+ccflags-y += -DQIB_KERN_TYPE=0 -DQIB_IDSTR='QLogic kernel.org driver'
+
+obj-$(CONFIG_INFINIBAND_QIB) += ib_qib.o
+
+ib_qib-y := \
+   qib_cq.o \
+   qib_diag.o \
+   qib_dma.o \
+   qib_driver.o \
+   qib_eeprom.o \
+   qib_file_ops.o \
+   qib_fs.o \
+   qib_init.o \
+   qib_intr.o \
+   qib_keys.o \
+   qib_mad.o \
+   qib_mmap.o \
+   qib_mr.o \
+   qib_pcie.o \
+   qib_pio_copy.o \
+   qib_qp.o \
+   qib_qsfp.o \
+   qib_rc.o \
+   qib_ruc.o \
+   qib_sdma.o \
+   qib_srq.o \
+   qib_sysfs.o \
+   qib_trace.o \
+   qib_twsi.o \
+   qib_tx.o \
+   qib_uc.o \
+   qib_ud.o \
+   qib_user_pages.o \
+   qib_user_sdma.o \
+   qib_verbs_mcast.o \
+   qib_iba7220.o \
+   qib_sd7220.o \
+   qib_sd7220_img.o \
+   qib_iba7322.o \
+   qib_verbs.o
+
+# 6120 has no fallback if no MSI interrupts, others can do INTx
+ib_qib-$(CONFIG_PCI_MSI) += qib_iba6120.o
+
+ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o
+ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 13/53] IB/qib: Add qib_driver.c

2009-11-19 Thread Ralph Campbell
creates the qib_driver.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_driver.c |  793 
 1 files changed, 793 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_driver.c

diff --git a/drivers/infiniband/hw/qib/qib_driver.c 
b/drivers/infiniband/hw/qib/qib_driver.c
new file mode 100644
index 000..5c68b97
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_driver.c
@@ -0,0 +1,793 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/spinlock.h
+#include linux/pci.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/netdevice.h
+#include linux/vmalloc.h
+
+#include qib.h
+
+/*
+ * The size has to be longer than this string, so we can append
+ * board/chip information to it in the init code.
+ */
+const char ib_qib_version[] = QIB_IDSTR \n;
+
+DEFINE_SPINLOCK(qib_devs_lock);
+LIST_HEAD(qib_dev_list);
+DEFINE_MUTEX(qib_mutex);   /* general driver use */
+
+unsigned qib_debug;
+module_param_named(debug, qib_debug, uint, S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(debug, mask for debug prints);
+
+unsigned qib_ibmtu;
+module_param_named(ibmtu, qib_ibmtu, uint, S_IRUGO);
+MODULE_PARM_DESC(ibmtu, Set max IB MTU (0=2KB, 1=256, 2=512, ... 5=4096);
+
+unsigned qib_compat_ddr_negotiate = 1;
+module_param_named(compat_ddr_negotiate, qib_compat_ddr_negotiate, uint,
+  S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(compat_ddr_negotiate,
+Attempt pre-IBTA 1.2 DDR speed negotiation);
+
+MODULE_LICENSE(Dual BSD/GPL);
+MODULE_AUTHOR(QLogic supp...@qlogic.com);
+MODULE_DESCRIPTION(QLogic IB driver);
+
+/*
+ * QIB_PIO_MAXIBHDR is the max IB header size allowed for in our
+ * PIO send buffers.  This is well beyond anything currently
+ * defined in the InfiniBand spec.
+ */
+#define QIB_PIO_MAXIBHDR 128
+
+struct qlogic_ib_stats qib_stats;
+
+const char *qib_get_unit_name(int unit)
+{
+   static char iname[16];
+
+   snprintf(iname, sizeof iname, infinipath%u, unit);
+   return iname;
+}
+
+/*
+ * Return count of units with at least one port ACTIVE.
+ */
+int qib_count_active_units(void)
+{
+   struct qib_devdata *dd;
+   struct qib_pportdata *ppd;
+   unsigned long flags;
+   int pidx, nunits_active = 0;
+
+   spin_lock_irqsave(qib_devs_lock, flags);
+   list_for_each_entry(dd, qib_dev_list, list) {
+   if (!(dd-flags  QIB_PRESENT) || !dd-kregbase)
+   continue;
+   for (pidx = 0; pidx  dd-num_pports; ++pidx) {
+   ppd = dd-pport + pidx;
+   if (ppd-lid  (ppd-lflags  (QIBL_LINKINIT |
+QIBL_LINKARMED | QIBL_LINKACTIVE))) {
+   nunits_active++;
+   break;
+   }
+   }
+   }
+   spin_unlock_irqrestore(qib_devs_lock, flags);
+   return nunits_active;
+}
+
+/*
+ * Return count of all units, optionally return in arguments
+ * the number of usable (present) units, and the number of
+ * ports that are up.
+ */
+int qib_count_units(int *npresentp, int *nupp)
+{
+   int nunits = 0, npresent = 0, nup = 0;
+   struct qib_devdata *dd;
+   unsigned long flags;
+   int pidx;
+   struct qib_pportdata *ppd;
+
+   spin_lock_irqsave(qib_devs_lock, flags);
+
+   list_for_each_entry(dd, qib_dev_list, list

[PATCH 14/53] IB/qib: Add qib_eeprom.c

2009-11-19 Thread Ralph Campbell
creates the qib_eeprom.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_eeprom.c |  460 
 1 files changed, 460 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_eeprom.c

diff --git a/drivers/infiniband/hw/qib/qib_eeprom.c 
b/drivers/infiniband/hw/qib/qib_eeprom.c
new file mode 100644
index 000..7a6fe41
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_eeprom.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/delay.h
+#include linux/pci.h
+#include linux/vmalloc.h
+
+#include qib.h
+
+/*
+ * Functions specific to the serial EEPROM on cards handled by ib_qib.
+ * The actual serail interface code is in qib_twsi.c. This file is a client
+ */
+
+/**
+ * qib_eeprom_read - receives bytes from the eeprom via I2C
+ * @dd: the qlogic_ib device
+ * @eeprom_offset: address to read from
+ * @buffer: where to store result
+ * @len: number of bytes to receive
+ */
+int qib_eeprom_read(struct qib_devdata *dd, u8 eeprom_offset,
+   void *buff, int len)
+{
+   int ret;
+
+   ret = mutex_lock_interruptible(dd-eep_lock);
+   if (!ret) {
+   ret = qib_twsi_reset(dd);
+   if (ret)
+   qib_dev_err(dd, TWSI Reset failed, EEPROM Rd\n);
+   else
+   ret = qib_twsi_blk_rd(dd, dd-twsi_eeprom_dev,
+ eeprom_offset, buff, len);
+   mutex_unlock(dd-eep_lock);
+   }
+
+   return ret;
+}
+
+/*
+ * Actually update the eeprom, first doing write enable if
+ * needed, then restoring write enable state.
+ * Must be called with eep_lock held
+ */
+static int eeprom_write_with_enable(struct qib_devdata *dd, u8 offset,
+const void *buf, int len)
+{
+   int ret, pwen;
+
+   pwen = dd-f_eeprom_wen(dd, 1);
+   ret = qib_twsi_reset(dd);
+   if (ret)
+   qib_dev_err(dd, TWSI Reset failed, EEPROM Wr\n);
+   else
+   ret = qib_twsi_blk_wr(dd, dd-twsi_eeprom_dev,
+ offset, buf, len);
+   dd-f_eeprom_wen(dd, pwen);
+   return ret;
+}
+
+/**
+ * qib_eeprom_write - writes data to the eeprom via I2C
+ * @dd: the qlogic_ib device
+ * @eeprom_offset: where to place data
+ * @buffer: data to write
+ * @len: number of bytes to write
+ */
+int qib_eeprom_write(struct qib_devdata *dd, u8 eeprom_offset,
+const void *buff, int len)
+{
+   int ret;
+
+   ret = mutex_lock_interruptible(dd-eep_lock);
+   if (!ret) {
+   ret = eeprom_write_with_enable(dd, eeprom_offset, buff, len);
+   mutex_unlock(dd-eep_lock);
+   }
+
+   return ret;
+}
+
+static u8 flash_csum(struct qib_flash *ifp, int adjust)
+{
+   u8 *ip = (u8 *) ifp;
+   u8 csum = 0, len;
+
+   /*
+* Limit length checksummed to max length of actual data.
+* Checksum of erased eeprom will still be bad, but we avoid
+* reading past the end of the buffer we were passed.
+*/
+   len = ifp-if_length;
+   if (len  sizeof(struct qib_flash))
+   len = sizeof(struct qib_flash);
+   while (len--)
+   csum += *ip++;
+   csum -= ifp-if_csum;
+   csum = ~csum;
+   if (adjust)
+   ifp-if_csum = csum;
+
+   return csum;
+}
+
+/**
+ * qib_get_eeprom_info- get

[PATCH 16/53] IB/qib: Add qib_fs.c

2009-11-19 Thread Ralph Campbell
creates the qib_fs.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_fs.c |  549 
 1 files changed, 549 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_fs.c

diff --git a/drivers/infiniband/hw/qib/qib_fs.c 
b/drivers/infiniband/hw/qib/qib_fs.c
new file mode 100644
index 000..629ff7e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_fs.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2006 PathScale, Inc. 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/module.h
+#include linux/fs.h
+#include linux/mount.h
+#include linux/pagemap.h
+#include linux/init.h
+#include linux/namei.h
+
+#include qib.h
+
+#define QIBFS_MAGIC 0x726a77
+
+static struct super_block *qib_super;
+
+#define private2dd(file) ((file)-f_dentry-d_inode-i_private)
+
+static int qibfs_mknod(struct inode *dir, struct dentry *dentry,
+  int mode, const struct file_operations *fops,
+  void *data)
+{
+   int error;
+   struct inode *inode = new_inode(dir-i_sb);
+
+   if (!inode) {
+   error = -EPERM;
+   goto bail;
+   }
+
+   inode-i_mode = mode;
+   inode-i_uid = 0;
+   inode-i_gid = 0;
+   inode-i_blocks = 0;
+   inode-i_atime = CURRENT_TIME;
+   inode-i_mtime = inode-i_atime;
+   inode-i_ctime = inode-i_atime;
+   inode-i_private = data;
+   if ((mode  S_IFMT) == S_IFDIR) {
+   inode-i_op = simple_dir_inode_operations;
+   inc_nlink(inode);
+   inc_nlink(dir);
+   }
+
+   inode-i_fop = fops;
+
+   d_instantiate(dentry, inode);
+   error = 0;
+
+bail:
+   return error;
+}
+
+static int create_file(const char *name, mode_t mode,
+  struct dentry *parent, struct dentry **dentry,
+  const struct file_operations *fops, void *data)
+{
+   int error;
+
+   *dentry = NULL;
+   mutex_lock(parent-d_inode-i_mutex);
+   *dentry = lookup_one_len(name, parent, strlen(name));
+   if (!IS_ERR(*dentry))
+   error = qibfs_mknod(parent-d_inode, *dentry,
+   mode, fops, data);
+   else
+   error = PTR_ERR(*dentry);
+   mutex_unlock(parent-d_inode-i_mutex);
+
+   return error;
+}
+
+static ssize_t driver_stats_read(struct file *file, char __user *buf,
+size_t count, loff_t *ppos)
+{
+   return simple_read_from_buffer(buf, count, ppos, qib_stats,
+  sizeof qib_stats);
+}
+
+/*
+ * driver stats field names, one line per stat, single string.  Used by
+ * programs like ipathstats to print the stats in a way which works for
+ * different versions of drivers, without changing program source.
+ * if qlogic_ib_stats changes, this needs to change.  Names need to be
+ * 12 chars or less (w/o newline), for proper display by ipathstats utility.
+ */
+static const char qib_statnames[] =
+   KernIntr\n
+   ErrorIntr\n
+   Tx_Errs\n
+   Rcv_Errs\n
+   H/W_Errs\n
+   NoPIOBufs\n
+   CtxtsOpen\n
+   RcvLen_Errs\n
+   EgrBufFull\n
+   EgrHdrFull\n
+   ;
+
+static ssize_t driver_names_read(struct file *file, char __user *buf,
+size_t count, loff_t *ppos)
+{
+   return simple_read_from_buffer(buf, count, ppos, qib_statnames,
+   sizeof qib_statnames - 1); /* no null

[PATCH 20/53] IB/qib: Add qib_init.c

2009-11-19 Thread Ralph Campbell
creates the qib_init.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_init.c | 1618 ++
 1 files changed, 1618 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_init.c

diff --git a/drivers/infiniband/hw/qib/qib_init.c 
b/drivers/infiniband/hw/qib/qib_init.c
new file mode 100644
index 000..dbf2b4b
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -0,0 +1,1618 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/pci.h
+#include linux/netdevice.h
+#include linux/vmalloc.h
+#include linux/delay.h
+#include linux/idr.h
+
+#include qib.h
+#include qib_common.h
+
+/*
+ * min buffers we want to have per context, after driver
+ */
+#define QIB_MIN_USER_CTXT_BUFCNT 7
+
+#define QLOGIC_IB_R_SOFTWARE_MASK 0xFF
+#define QLOGIC_IB_R_SOFTWARE_SHIFT 24
+#define QLOGIC_IB_R_EMULATOR_MASK (1ULL62)
+
+/*
+ * Number of ctxts we are configured to use (to allow for more pio
+ * buffers per ctxt, etc.)  Zero means use chip value.
+ */
+ushort qib_cfgctxts;
+module_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO);
+MODULE_PARM_DESC(cfgctxts, Set max number of contexts to use);
+
+/*
+ * If set, do not write to any regs if avoidable, hack to allow
+ * check for deranged default register values.
+ */
+ushort qib_mini_init;
+module_param_named(mini_init, qib_mini_init, ushort, S_IRUGO);
+MODULE_PARM_DESC(mini_init, If set, do minimal diag init);
+
+unsigned qib_n_krcv_queues;
+module_param_named(krcvqs, qib_n_krcv_queues, uint, S_IRUGO);
+MODULE_PARM_DESC(krcvqs, number of kernel receive queues per IB port);
+
+/*
+ * qib_wc_pat parameter:
+ *  0 is WC via MTRR
+ *  1 is WC via PAT
+ *  If PAT initialization fails, code reverts back to MTRR
+ */
+unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */
+module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO);
+MODULE_PARM_DESC(wc_pat, enable write-combining via PAT mechanism);
+
+static void verify_interrupt(unsigned long);
+
+static struct idr qib_unit_table;
+
+/* set number of contexts we'll actually use */
+void qib_set_ctxtcnt(struct qib_devdata *dd)
+{
+   if (!qib_cfgctxts)
+   dd-cfgctxts = dd-ctxtcnt;
+   else if (qib_cfgctxts  dd-num_pports) {
+   dd-cfgctxts = dd-ctxtcnt;
+   qib_dbg(Configured to use too few ctxts (%u); using %u\n,
+   qib_cfgctxts, dd-cfgctxts);
+   } else if (qib_cfgctxts = dd-ctxtcnt) {
+   dd-cfgctxts = qib_cfgctxts;
+   qib_cdbg(INIT, Configured to use %u ctxts\n, dd-cfgctxts);
+   } else {
+   dd-cfgctxts = dd-ctxtcnt;
+   qib_dbg(Configured to use too many ctxts (%u); using %u\n,
+   qib_cfgctxts, dd-cfgctxts);
+   }
+}
+
+/*
+ * Common code for creating the receive context array.
+ */
+int qib_create_ctxts(struct qib_devdata *dd)
+{
+   unsigned i;
+   int ret;
+
+   /*
+* Allocate full ctxtcnt array, rather than just cfgctxts, because
+* cleanup iterates across all possible ctxts.
+*/
+   dd-rcd = kzalloc(sizeof(*dd-rcd) * dd-ctxtcnt, GFP_KERNEL);
+   if (!dd-rcd) {
+   qib_dev_err(dd, Unable to allocate ctxtdata array, 
+   failing\n);
+   ret = -ENOMEM;
+   goto done;
+   }
+
+   /* create (one or more) kctxt */
+   for (i = 0; i  dd

[PATCH 23/53] IB/qib: Add qib_mad.c

2009-11-19 Thread Ralph Campbell
creates the qib_mad.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_mad.c | 1867 +++
 1 files changed, 1867 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mad.c

diff --git a/drivers/infiniband/hw/qib/qib_mad.c 
b/drivers/infiniband/hw/qib/qib_mad.c
new file mode 100644
index 000..e89d9bf
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mad.c
@@ -0,0 +1,1867 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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 rdma/ib_smi.h
+
+#include qib.h
+#include qib_mad.h
+
+static int reply(struct ib_smp *smp)
+{
+   /*
+* The verbs framework will handle the directed/LID route
+* packet changes.
+*/
+   smp-method = IB_MGMT_METHOD_GET_RESP;
+   if (smp-mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)
+   smp-status |= IB_SMP_DIRECTION;
+   return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
+}
+
+static void qib_send_trap(struct qib_ibport *ibp, void *data, unsigned len)
+{
+   struct ib_mad_send_buf *send_buf;
+   struct ib_mad_agent *agent;
+   struct ib_smp *smp;
+   int ret;
+   unsigned long flags;
+   unsigned long timeout;
+
+   agent = ibp-send_agent;
+   if (!agent)
+   return;
+
+   /* o14-3.2.1 */
+   if (!(ppd_from_ibp(ibp)-lflags  QIBL_LINKACTIVE))
+   return;
+
+   /* o14-2 */
+   if (ibp-trap_timeout  time_before(jiffies, ibp-trap_timeout))
+   return;
+
+   send_buf = ib_create_send_mad(agent, 0, 0, 0, IB_MGMT_MAD_HDR,
+ IB_MGMT_MAD_DATA, GFP_ATOMIC);
+   if (IS_ERR(send_buf))
+   return;
+
+   smp = send_buf-mad;
+   smp-base_version = IB_MGMT_BASE_VERSION;
+   smp-mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
+   smp-class_version = 1;
+   smp-method = IB_MGMT_METHOD_TRAP;
+   ibp-tid++;
+   smp-tid = cpu_to_be64(ibp-tid);
+   smp-attr_id = IB_SMP_ATTR_NOTICE;
+   /* o14-1: smp-mkey = 0; */
+   memcpy(smp-data, data, len);
+
+   spin_lock_irqsave(ibp-lock, flags);
+   if (!ibp-sm_ah) {
+   if (ibp-sm_lid != be16_to_cpu(IB_LID_PERMISSIVE)) {
+   struct ib_ah *ah;
+   struct ib_ah_attr attr;
+
+   memset(attr, 0, sizeof attr);
+   attr.dlid = ibp-sm_lid;
+   attr.port_num = ppd_from_ibp(ibp)-port;
+   ah = ib_create_ah(ibp-qp0-ibqp.pd, attr);
+   if (IS_ERR(ah))
+   ret = -EINVAL;
+   else {
+   send_buf-ah = ah;
+   ibp-sm_ah = to_iah(ah);
+   ret = 0;
+   }
+   } else
+   ret = -EINVAL;
+   } else {
+   send_buf-ah = ibp-sm_ah-ibah;
+   ret = 0;
+   }
+   spin_unlock_irqrestore(ibp-lock, flags);
+
+   if (!ret)
+   ret = ib_post_send_mad(send_buf, NULL);
+   if (!ret) {
+   /* 4.096 usec. */
+   timeout = (4096 * (1UL  ibp-subnet_timeout)) / 1000;
+   ibp-trap_timeout = jiffies + usecs_to_jiffies(timeout);
+   } else {
+   ib_free_send_mad(send_buf);
+   ibp-trap_timeout = 0;
+   }
+}
+
+/*
+ * Send a bad [PQ]_Key

[PATCH 24/53] IB/qib: Add qib_mad.h

2009-11-19 Thread Ralph Campbell
creates the qib_mad.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_mad.h |  333 +++
 1 files changed, 333 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mad.h

diff --git a/drivers/infiniband/hw/qib/qib_mad.h 
b/drivers/infiniband/hw/qib/qib_mad.h
new file mode 100644
index 000..57cab0d
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mad.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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.
+ */
+
+#define IB_SMP_UNSUP_VERSIONcpu_to_be16(0x0004)
+#define IB_SMP_UNSUP_METHOD cpu_to_be16(0x0008)
+#define IB_SMP_UNSUP_METH_ATTR  cpu_to_be16(0x000C)
+#define IB_SMP_INVALID_FIELDcpu_to_be16(0x001C)
+
+struct ib_node_info {
+   u8 base_version;
+   u8 class_version;
+   u8 node_type;
+   u8 num_ports;
+   __be64 sys_guid;
+   __be64 node_guid;
+   __be64 port_guid;
+   __be16 partition_cap;
+   __be16 device_id;
+   __be32 revision;
+   u8 local_port_num;
+   u8 vendor_id[3];
+} __attribute__ ((packed));
+
+struct ib_mad_notice_attr {
+   u8 generic_type;
+   u8 prod_type_msb;
+   __be16 prod_type_lsb;
+   __be16 trap_num;
+   __be16 issuer_lid;
+   __be16 toggle_count;
+
+   union {
+   struct {
+   u8  details[54];
+   } raw_data;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* where violation happened */
+   u8  port_num;   /* where violation happened */
+   } __attribute__ ((packed)) ntc_129_131;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* LID where change occured */
+   u8  reserved2;
+   u8  local_changes;  /* low bit - local changes */
+   __be32  new_cap_mask;   /* new capability mask */
+   u8  reserved3;
+   u8  change_flags;   /* low 3 bits only */
+   } __attribute__ ((packed)) ntc_144;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;/* lid where sys guid changed */
+   __be16  reserved2;
+   __be64  new_sys_guid;
+   } __attribute__ ((packed)) ntc_145;
+
+   struct {
+   __be16  reserved;
+   __be16  lid;
+   __be16  dr_slid;
+   u8  method;
+   u8  reserved2;
+   __be16  attr_id;
+   __be32  attr_mod;
+   __be64  mkey;
+   u8  reserved3;
+   u8  dr_trunc_hop;
+   u8  dr_rtn_path[30];
+   } __attribute__ ((packed)) ntc_256;
+
+   struct {
+   __be16  reserved;
+   __be16  lid1;
+   __be16  lid2;
+   __be32  key;
+   __be32  sl_qp1; /* SL: high 4 bits */
+   __be32  qp2;/* high 8 bits reserved */
+   union ib_gidgid1;
+   union ib_gidgid2

[PATCH 25/53] IB/qib: Add qib_mmap.c

2009-11-19 Thread Ralph Campbell
creates the qib_mmap.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_mmap.c |  173 ++
 1 files changed, 173 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mmap.c

diff --git a/drivers/infiniband/hw/qib/qib_mmap.c 
b/drivers/infiniband/hw/qib/qib_mmap.c
new file mode 100644
index 000..ae15d38
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mmap.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. 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/module.h
+#include linux/vmalloc.h
+#include linux/mm.h
+#include linux/errno.h
+#include asm/pgtable.h
+
+#include qib_verbs.h
+
+/**
+ * qib_release_mmap_info - free mmap info structure
+ * @ref: a pointer to the kref within struct qib_mmap_info
+ */
+void qib_release_mmap_info(struct kref *ref)
+{
+   struct qib_mmap_info *ip =
+   container_of(ref, struct qib_mmap_info, ref);
+   struct qib_ibdev *dev = to_idev(ip-context-device);
+
+   spin_lock_irq(dev-pending_lock);
+   list_del(ip-pending_mmaps);
+   spin_unlock_irq(dev-pending_lock);
+
+   vfree(ip-obj);
+   kfree(ip);
+}
+
+/*
+ * open and close keep track of how many times the CQ is mapped,
+ * to avoid releasing it.
+ */
+static void qib_vma_open(struct vm_area_struct *vma)
+{
+   struct qib_mmap_info *ip = vma-vm_private_data;
+
+   kref_get(ip-ref);
+}
+
+static void qib_vma_close(struct vm_area_struct *vma)
+{
+   struct qib_mmap_info *ip = vma-vm_private_data;
+
+   kref_put(ip-ref, qib_release_mmap_info);
+}
+
+static struct vm_operations_struct qib_vm_ops = {
+   .open = qib_vma_open,
+   .close =qib_vma_close,
+};
+
+/**
+ * qib_mmap - create a new mmap region
+ * @context: the IB user context of the process making the mmap() call
+ * @vma: the VMA to be initialized
+ * Return zero if the mmap is OK. Otherwise, return an errno.
+ */
+int qib_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
+{
+   struct qib_ibdev *dev = to_idev(context-device);
+   unsigned long offset = vma-vm_pgoff  PAGE_SHIFT;
+   unsigned long size = vma-vm_end - vma-vm_start;
+   struct qib_mmap_info *ip, *pp;
+   int ret = -EINVAL;
+
+   /*
+* Search the device's list of objects waiting for a mmap call.
+* Normally, this list is very short since a call to create a
+* CQ, QP, or SRQ is soon followed by a call to mmap().
+*/
+   spin_lock_irq(dev-pending_lock);
+   list_for_each_entry_safe(ip, pp, dev-pending_mmaps,
+pending_mmaps) {
+   /* Only the creator is allowed to mmap the object */
+   if (context != ip-context || (__u64) offset != ip-offset)
+   continue;
+   /* Don't allow a mmap larger than the object. */
+   if (size  ip-size)
+   break;
+
+   list_del_init(ip-pending_mmaps);
+   spin_unlock_irq(dev-pending_lock);
+
+   ret = remap_vmalloc_range(vma, ip-obj, 0);
+   if (ret)
+   goto done;
+   vma-vm_ops = qib_vm_ops;
+   vma-vm_private_data = ip;
+   qib_vma_open(vma);
+   goto done;
+   }
+   spin_unlock_irq(dev-pending_lock);
+done:
+   return ret;
+}
+
+/*
+ * Allocate information for qib_mmap
+ */
+struct qib_mmap_info *qib_create_mmap_info(struct qib_ibdev *dev,
+  u32

[PATCH 26/53] IB/qib: Add qib_mr.c

2009-11-19 Thread Ralph Campbell
creates the qib_mr.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_mr.c |  455 
 1 files changed, 455 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_mr.c

diff --git a/drivers/infiniband/hw/qib/qib_mr.c 
b/drivers/infiniband/hw/qib/qib_mr.c
new file mode 100644
index 000..f283c3b
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_mr.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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 rdma/ib_umem.h
+#include rdma/ib_smi.h
+
+#include qib.h
+
+/* Fast memory region */
+struct qib_fmr {
+   struct ib_fmr ibfmr;
+   u8 page_shift;
+   struct qib_mregion mr;/* must be last */
+};
+
+static inline struct qib_fmr *to_ifmr(struct ib_fmr *ibfmr)
+{
+   return container_of(ibfmr, struct qib_fmr, ibfmr);
+}
+
+/**
+ * qib_get_dma_mr - get a DMA memory region
+ * @pd: protection domain for this memory region
+ * @acc: access flags
+ *
+ * Returns the memory region on success, otherwise returns an errno.
+ * Note that all DMA addresses should be created via the
+ * struct ib_dma_mapping_ops functions (see qib_dma.c).
+ */
+struct ib_mr *qib_get_dma_mr(struct ib_pd *pd, int acc)
+{
+   struct qib_ibdev *dev = to_idev(pd-device);
+   struct qib_mr *mr;
+   struct ib_mr *ret;
+   unsigned long flags;
+
+   if (to_ipd(pd)-user) {
+   ret = ERR_PTR(-EPERM);
+   goto bail;
+   }
+
+   mr = kzalloc(sizeof *mr, GFP_KERNEL);
+   if (!mr) {
+   ret = ERR_PTR(-ENOMEM);
+   goto bail;
+   }
+
+   mr-mr.access_flags = acc;
+   atomic_set(mr-mr.refcount, 0);
+
+   spin_lock_irqsave(dev-lk_table.lock, flags);
+   if (!dev-dma_mr)
+   dev-dma_mr = mr-mr;
+   spin_unlock_irqrestore(dev-lk_table.lock, flags);
+
+   ret = mr-ibmr;
+
+bail:
+   return ret;
+}
+
+static struct qib_mr *alloc_mr(int count, struct qib_lkey_table *lk_table)
+{
+   struct qib_mr *mr;
+   int m, i = 0;
+
+   /* Allocate struct plus pointers to first level page tables. */
+   m = (count + QIB_SEGSZ - 1) / QIB_SEGSZ;
+   mr = kmalloc(sizeof *mr + m * sizeof mr-mr.map[0], GFP_KERNEL);
+   if (!mr)
+   goto done;
+
+   /* Allocate first level page tables. */
+   for (; i  m; i++) {
+   mr-mr.map[i] = kmalloc(sizeof *mr-mr.map[0], GFP_KERNEL);
+   if (!mr-mr.map[i])
+   goto bail;
+   }
+   mr-mr.mapsz = m;
+
+   /*
+* ib_reg_phys_mr() will initialize mr-ibmr except for
+* lkey and rkey.
+*/
+   if (!qib_alloc_lkey(lk_table, mr-mr))
+   goto bail;
+   mr-ibmr.lkey = mr-mr.lkey;
+   mr-ibmr.rkey = mr-mr.lkey;
+
+   atomic_set(mr-mr.refcount, 0);
+   goto done;
+
+bail:
+   while (i)
+   kfree(mr-mr.map[--i]);
+   kfree(mr);
+   mr = NULL;
+
+done:
+   return mr;
+}
+
+/**
+ * qib_reg_phys_mr - register a physical memory region
+ * @pd: protection domain for this memory region
+ * @buffer_list: pointer to the list of physical buffers to register
+ * @num_phys_buf: the number of physical buffers to register
+ * @iova_start: the starting address passed over IB which maps to this MR
+ *
+ * Returns the memory region on success, otherwise returns an errno.
+ */
+struct ib_mr *qib_reg_phys_mr(struct ib_pd *pd

[PATCH 28/53] IB/qib: Add qib_pio_copy.c

2009-11-19 Thread Ralph Campbell
creates the qib_pio_copy.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_pio_copy.c |   64 ++
 1 files changed, 64 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_pio_copy.c

diff --git a/drivers/infiniband/hw/qib/qib_pio_copy.c 
b/drivers/infiniband/hw/qib/qib_pio_copy.c
new file mode 100644
index 000..10b8c44
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_pio_copy.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009 QLogic Corporation. 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 qib.h
+
+/**
+ * qib_pio_copy - copy data to MMIO space, in multiples of 32-bits
+ * @to: destination, in MMIO space (must be 64-bit aligned)
+ * @from: source (must be 64-bit aligned)
+ * @count: number of 32-bit quantities to copy
+ *
+ * Copy data from kernel space to MMIO space, in multiples of 32 bits at a
+ * time.  Order of access is not guaranteed, nor is a memory barrier
+ * performed afterwards.
+ */
+void qib_pio_copy(void __iomem *to, const void *from, size_t count)
+{
+#ifdef CONFIG_64BIT
+   u64 __iomem *dst = to;
+   const u64 *src = from;
+   const u64 *end = src + (count  1);
+
+   while (src  end)
+   __raw_writeq(*src++, dst++);
+   if (count  1)
+   __raw_writel(*(const u32 *)src, dst);
+#else
+   u32 __iomem *dst = to;
+   const u32 *src = from;
+   const u32 *end = src + count;
+
+   while (src  end)
+   __raw_writel(*src++, dst++);
+#endif
+}

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 30/53] IB/qib: Add qib_qsfp.c

2009-11-19 Thread Ralph Campbell
creates the qib_qsfp.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_qsfp.c |  593 ++
 1 files changed, 593 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qsfp.c

diff --git a/drivers/infiniband/hw/qib/qib_qsfp.c 
b/drivers/infiniband/hw/qib/qib_qsfp.c
new file mode 100644
index 000..5ffeddf
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qsfp.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/delay.h
+#include linux/pci.h
+#include linux/vmalloc.h
+
+#include qib.h
+#include qib_qsfp.h
+
+/*
+ * QSFP support for ib_qib driver, using Two Wire Serial Interface driver
+ * in qib_twsi.c
+ */
+#define QSFP_MAX_RETRY 4
+
+static int qsfp_read(struct qib_pportdata *ppd, int addr, void *bp, int len)
+{
+   struct qib_devdata *dd = ppd-dd;
+   u32 out, mask;
+   int ret, cnt, pass = 0;
+   int stuck = 0;
+   u8 *buff = bp;
+
+   qib_cdbg(VERBOSE, Grabbing Mutex for QSFP in %d:%d\n, dd-unit,
+ppd-port);
+   ret = mutex_lock_interruptible(dd-eep_lock);
+   if (ret)
+   goto no_unlock;
+
+   if (dd-twsi_eeprom_dev == QIB_TWSI_NO_DEV) {
+   qib_dbg(QSFP read on board without QSFP\n);
+   ret = -ENXIO;
+   goto bail;
+   }
+
+   /*
+* We presume, if we are called at all, that this board has
+* QSFP. This is on the same i2c chain as the legacy parts,
+* but only responds if the module is selected via GPIO pins.
+* Further, there are very long setup and hold requirements
+* on MODSEL.
+*/
+   mask = QSFP_GPIO_MOD_SEL_N | QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
+   out = QSFP_GPIO_MOD_RST_N | QSFP_GPIO_LP_MODE;
+   if (ppd-hw_pidx) {
+   mask = QSFP_GPIO_PORT2_SHIFT;
+   out = QSFP_GPIO_PORT2_SHIFT;
+   }
+
+   dd-f_gpio_mod(dd, out, mask, mask);
+
+   /*
+* Module could take up to 2 Msec to respond to MOD_SEL, and there
+* is no way to tell if it is ready, so we must wait.
+*/
+   msleep(2);
+
+   /* Make sure TWSI bus is in sane state. */
+   ret = qib_twsi_reset(dd);
+   if (ret) {
+   qib_dev_porterr(dd, ppd-port, TWSI Reset failed, QSFP Rd\n);
+   ret = -EIO;
+   stuck = 1;
+   goto deselect;
+   }
+
+   /* All QSFP modules are at A0 */
+
+   cnt = 0;
+   while (cnt  len) {
+   unsigned in_page;
+   int wlen = len - cnt;
+   in_page = addr % QSFP_PAGESIZE;
+   if ((in_page + wlen)  QSFP_PAGESIZE)
+   wlen = QSFP_PAGESIZE - in_page;
+   ret = qib_twsi_blk_rd(dd, QSFP_DEV, addr, buff + cnt, wlen);
+   /* Some QSFP's fail first try. Retry as experiment */
+   if (ret  cnt == 0  ++pass  QSFP_MAX_RETRY)
+   continue;
+   if (ret) {
+   /* qib_twsi_blk_rd() 1 for error, else 0 */
+   ret = -EIO;
+   goto deselect;
+   }
+   addr += wlen;
+   cnt += wlen;
+   }
+   ret = cnt;
+
+deselect:
+   /*
+* Module could take up to 10 uSec after transfer before
+* ready to respond to MOD_SEL negation, and there is no way
+* to tell

[PATCH 31/53] IB/qib: Add qib_qsfp.h

2009-11-19 Thread Ralph Campbell
creates the qib_qsfp.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_qsfp.h |  183 ++
 1 files changed, 183 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_qsfp.h

diff --git a/drivers/infiniband/hw/qib/qib_qsfp.h 
b/drivers/infiniband/hw/qib/qib_qsfp.h
new file mode 100644
index 000..01ea507
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_qsfp.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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.
+ */
+/* QSFP support common definitions, for ib_qib driver */
+
+#define QSFP_DEV 0xA0
+#define QSFP_PWR_LAG_MSEC 2000
+
+/*
+ * Below are masks for various QSFP signals, for Port 1.
+ * Port2 equivalents are shifted by QSFP_GPIO_PORT2_SHIFT.
+ * _N means asserted low
+ */
+#define QSFP_GPIO_MOD_SEL_N (4)
+#define QSFP_GPIO_MOD_PRS_N (8)
+#define QSFP_GPIO_INT_N (0x10)
+#define QSFP_GPIO_MOD_RST_N (0x20)
+#define QSFP_GPIO_LP_MODE (0x40)
+#define QSFP_GPIO_PORT2_SHIFT 5
+
+#define QSFP_PAGESIZE 128
+/* Defined fields that QLogic requires of qualified cables */
+/* Byte 0 is Identifier, not checked */
+/* Byte 1 is reserved status MSB */
+/* Byte 2 is status LSB We only care that D2 Flat Mem is set. */
+/*
+ * Rest of first 128 not used, although 127 is reserved for page select
+ * if module is not Flat memory.
+ */
+/* Byte 128 is Identifier: must be 0x0c for QSFP, or 0x0d for QSFP+ */
+#define QSFP_MOD_ID_OFFS 128
+/*
+ * Byte 129 is Extended Identifier. We only care about D7,D6: Power class
+ *  0:1.5W, 1:2.0W, 2:2.5W, 3:3.5W
+ */
+#define QSFP_MOD_PWR_OFFS 129
+/* Byte 130 is Connector type. Not QLogic req'd */
+/* Bytes 131..138 are Transceiver types, bit maps for various tech, none IB */
+/* Byte 139 is encoding. code 0x01 is 8b10b. Not QLogic req'd */
+/* byte 140 is nominal bit-rate, in units of 100Mbits/sec Not QLogic req'd */
+/* Byte 141 is Extended Rate Select. Not QLogic req'd */
+/* Bytes 142..145 are lengths for various fiber types. Not QLogic req'd */
+/* Byte 146 is length for Copper. Units of 1 meter */
+#define QSFP_MOD_LEN_OFFS 146
+/*
+ * Byte 147 is Device technology. D0..3 not Qlogc req'd
+ * D4..7 select from 15 choices, translated by table:
+ */
+#define QSFP_MOD_TECH_OFFS 147
+extern const char *const qib_qsfp_devtech[16];
+/* Length is only valid if technology is copper */
+#define QSFP_IS_CU(tech) ((0xED00  ((tech)  4))  1)
+#define QSFP_TECH_1490 9
+
+#define QSFP_OUI(oui) (((unsigned)oui[0]  16) | ((unsigned)oui[1]  8) | \
+   oui[2])
+#define QSFP_OUI_AMPHENOL 0x415048
+#define QSFP_OUI_FINISAR  0x009065
+#define QSFP_OUI_GORE 0x002177
+
+/* Bytes 148..163 are Vendor Name, Left-justified Blank-filled */
+#define QSFP_VEND_OFFS 148
+#define QSFP_VEND_LEN 16
+/* Byte 164 is IB Extended tranceiver codes Bits D0..3 are SDR,DDR,QDR,EDR */
+#define QSFP_IBXCV_OFFS 164
+/* Bytes 165..167 are Vendor OUI number */
+#define QSFP_VOUI_OFFS 165
+#define QSFP_VOUI_LEN 3
+/* Bytes 168..183 are Vendor Part Number, string */
+#define QSFP_PN_OFFS 168
+#define QSFP_PN_LEN 16
+/* Bytes 184,185 are Vendor Rev. Left Justified, Blank-filled */
+#define QSFP_REV_OFFS 184
+#define QSFP_REV_LEN 2
+/*
+ * Bytes 186,187 are Wavelength, if Optical. Not Qlogic req'd
+ *  If copper, they are attenuation in dB:
+ * Byte 186 is at 2.5Gb/sec (SDR), Byte 187 at 5.0Gb/sec (DDR)
+ */
+#define QSFP_ATTEN_OFFS 186
+#define QSFP_ATTEN_LEN 2
+/* Bytes 188,189 are Wavelength tolerance

[PATCH 33/53] IB/qib: Add qib_ruc.c

2009-11-19 Thread Ralph Campbell
creates the qib_ruc.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_ruc.c |  817 +++
 1 files changed, 817 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_ruc.c

diff --git a/drivers/infiniband/hw/qib/qib_ruc.c 
b/drivers/infiniband/hw/qib/qib_ruc.c
new file mode 100644
index 000..eb78d93
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_ruc.c
@@ -0,0 +1,817 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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/spinlock.h
+
+#include qib.h
+#include qib_mad.h
+
+/*
+ * Convert the AETH RNR timeout code into the number of microseconds.
+ */
+const u32 ib_qib_rnr_table[32] = {
+   655360, /* 00: 655.36 */
+   10, /* 01:.01 */
+   20, /* 02 .02 */
+   30, /* 03:.03 */
+   40, /* 04:.04 */
+   60, /* 05:.06 */
+   80, /* 06:.08 */
+   120,/* 07:.12 */
+   160,/* 08:.16 */
+   240,/* 09:.24 */
+   320,/* 0A:.32 */
+   480,/* 0B:.48 */
+   640,/* 0C:.64 */
+   960,/* 0D:.96 */
+   1280,   /* 0E:   1.28 */
+   1920,   /* 0F:   1.92 */
+   2560,   /* 10:   2.56 */
+   3840,   /* 11:   3.84 */
+   5120,   /* 12:   5.12 */
+   7680,   /* 13:   7.68 */
+   10240,  /* 14:  10.24 */
+   15360,  /* 15:  15.36 */
+   20480,  /* 16:  20.48 */
+   30720,  /* 17:  30.72 */
+   40960,  /* 18:  40.96 */
+   61440,  /* 19:  61.44 */
+   81920,  /* 1A:  81.92 */
+   122880, /* 1B: 122.88 */
+   163840, /* 1C: 163.84 */
+   245760, /* 1D: 245.76 */
+   327680, /* 1E: 327.68 */
+   491520  /* 1F: 491.52 */
+};
+
+/*
+ * Validate a RWQE and fill in the SGE state.
+ * Return 1 if OK.
+ */
+static int qib_init_sge(struct qib_qp *qp, struct qib_rwqe *wqe)
+{
+   int i, j, ret;
+   struct ib_wc wc;
+   struct qib_lkey_table *rkt;
+   struct qib_pd *pd;
+   struct qib_sge_state *ss;
+
+   rkt = to_idev(qp-ibqp.device)-lk_table;
+   pd = to_ipd(qp-ibqp.srq ? qp-ibqp.srq-pd : qp-ibqp.pd);
+   ss = qp-r_sge;
+   ss-sg_list = qp-r_sg_list;
+   qp-r_len = 0;
+   for (i = j = 0; i  wqe-num_sge; i++) {
+   if (wqe-sg_list[i].length == 0)
+   continue;
+   /* Check LKEY */
+   if (!qib_lkey_ok(rkt, pd, j ? ss-sg_list[j - 1] : ss-sge,
+wqe-sg_list[i], IB_ACCESS_LOCAL_WRITE))
+   goto bad_lkey;
+   qp-r_len += wqe-sg_list[i].length;
+   j++;
+   }
+   ss-num_sge = j;
+   ss-total_len = qp-r_len;
+   ret = 1;
+   goto bail;
+
+bad_lkey:
+   while (j) {
+   struct qib_sge *sge = --j ? ss-sg_list[j - 1] : ss-sge;
+
+   atomic_dec(sge-mr-refcount);
+   }
+   ss-num_sge = 0;
+   memset(wc, 0, sizeof(wc));
+   wc.wr_id = wqe-wr_id;
+   wc.status = IB_WC_LOC_PROT_ERR;
+   wc.opcode = IB_WC_RECV;
+   wc.qp = qp-ibqp;
+   /* Signal solicited completion event. */
+   qib_cq_enter(to_icq(qp-ibqp.recv_cq), wc, 1);
+   ret = 0;
+bail:
+   return ret;
+}
+
+/**
+ * qib_get_rwqe - copy the next RWQE into the QP's RWQE
+ * @qp: the QP
+ * @wr_id_only: update qp-r_wr_id only, not qp-r_sge
+ *
+ * Return -1 if there is a local error, 0 if no RWQE is available

[PATCH 34/53] IB/qib: Add qib_sd7220.c

2009-11-19 Thread Ralph Campbell
creates the qib_sd7220.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_sd7220.c | 1442 
 1 files changed, 1442 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sd7220.c

diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c 
b/drivers/infiniband/hw/qib/qib_sd7220.c
new file mode 100644
index 000..2230a09
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sd7220.c
@@ -0,0 +1,1442 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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.
+ */
+/*
+ * This file contains all of the code that is specific to the SerDes
+ * on the QLogic_IB 7220 chip.
+ */
+
+#include linux/pci.h
+#include linux/delay.h
+
+#include qib.h
+#include qib_7220.h
+
+/*
+ * Same as in qib_iba7220.c, but just the registers needed here.
+ * Could move whole set to qib_7220.h, but decided better to keep
+ * local.
+ */
+#define KREG_IDX(regname) (QIB_7220_##regname##_OFFS / sizeof(u64))
+#define kr_hwerrclear KREG_IDX(HwErrClear)
+#define kr_hwerrmask KREG_IDX(HwErrMask)
+#define kr_hwerrstatus KREG_IDX(HwErrStatus)
+#define kr_ibcstatus KREG_IDX(IBCStatus)
+#define kr_ibserdesctrl KREG_IDX(IBSerDesCtrl)
+#define kr_scratch KREG_IDX(Scratch)
+#define kr_xgxs_cfg KREG_IDX(XGXSCfg)
+/* these are used only here, not in qib_iba7220.c */
+#define kr_ibsd_epb_access_ctrl KREG_IDX(ibsd_epb_access_ctrl)
+#define kr_ibsd_epb_transaction_reg KREG_IDX(ibsd_epb_transaction_reg)
+#define kr_pciesd_epb_transaction_reg KREG_IDX(pciesd_epb_transaction_reg)
+#define kr_pciesd_epb_access_ctrl KREG_IDX(pciesd_epb_access_ctrl)
+#define kr_serdes_ddsrxeq0 KREG_IDX(SerDes_DDSRXEQ0)
+
+/*
+ * The IBSerDesMappTable is a memory that holds values to be stored in
+ * various SerDes registers by IBC.
+ */
+#define kr_serdes_maptable KREG_IDX(IBSerDesMappTable)
+
+/*
+ * Below used for sdnum parameter, selecting one of the two sections
+ * used for PCIe, or the single SerDes used for IB.
+ */
+#define PCIE_SERDES0 0
+#define PCIE_SERDES1 1
+
+/*
+ * The EPB requires addressing in a particular form. EPB_LOC() is intended
+ * to make #definitions a little more readable.
+ */
+#define EPB_ADDR_SHF 8
+#define EPB_LOC(chn, elt, reg) \
+   (((elt  0xf) | ((chn  7)  4) | ((reg  0x3f)  9))  \
+EPB_ADDR_SHF)
+#define EPB_IB_QUAD0_CS_SHF (25)
+#define EPB_IB_QUAD0_CS (1U   EPB_IB_QUAD0_CS_SHF)
+#define EPB_IB_UC_CS_SHF (26)
+#define EPB_PCIE_UC_CS_SHF (27)
+#define EPB_GLOBAL_WR (1U  (EPB_ADDR_SHF + 8))
+
+/* Forward declarations. */
+static int qib_sd7220_reg_mod(struct qib_devdata *dd, int sdnum, u32 loc,
+ u32 data, u32 mask);
+static int ibsd_mod_allchnls(struct qib_devdata *dd, int loc, int val,
+int mask);
+static int qib_sd_trimdone_poll(struct qib_devdata *dd);
+static void qib_sd_trimdone_monitor(struct qib_devdata *dd, const char *where);
+static int qib_sd_setvals(struct qib_devdata *dd);
+static int qib_sd_early(struct qib_devdata *dd);
+static int qib_sd_dactrim(struct qib_devdata *dd);
+static int qib_internal_presets(struct qib_devdata *dd);
+/* Tweak the register (CMUCTRL5) that contains the TRIMSELF controls */
+static int qib_sd_trimself(struct qib_devdata *dd, int val);
+static int epb_access(struct qib_devdata *dd, int sdnum, int claim);
+
+/*
+ * Below keeps track of whether the once per power-on initialization has
+ * been done, because uC code Version 1.32.17 or higher allows the uC to
+ * be reset

[PATCH 35/53] IB/qib: Add qib_sd7220_img.c

2009-11-19 Thread Ralph Campbell
creates the qib_sd7220_img.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_sd7220_img.c | 1081 
 1 files changed, 1081 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sd7220_img.c

diff --git a/drivers/infiniband/hw/qib/qib_sd7220_img.c 
b/drivers/infiniband/hw/qib/qib_sd7220_img.c
new file mode 100644
index 000..a1118fb
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sd7220_img.c
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (c) 2007, 2008 QLogic Corporation. 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.
+ */
+
+/*
+ * This file contains the memory image from the vendor, to be copied into
+ * the IB SERDES of the IBA7220 during initialization.
+ * The file also includes the two functions which use this image.
+ */
+#include linux/pci.h
+#include linux/delay.h
+
+#include qib.h
+#include qib_7220.h
+
+static unsigned char qib_sd7220_ib_img[] = {
+/**/0x02, 0x0A, 0x29, 0x02, 0x0A, 0x87, 0xE5, 0xE6,
+   0x30, 0xE6, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F,
+/*0010*/0x00, 0xE5, 0xE2, 0x30, 0xE4, 0x04, 0x7E, 0x01,
+   0x80, 0x02, 0x7E, 0x00, 0xEE, 0x5F, 0x60, 0x08,
+/*0020*/0x53, 0xF9, 0xF7, 0xE4, 0xF5, 0xFE, 0x80, 0x08,
+   0x7F, 0x0A, 0x12, 0x17, 0x31, 0x12, 0x0E, 0xA2,
+/*0030*/0x75, 0xFC, 0x08, 0xE4, 0xF5, 0xFD, 0xE5, 0xE7,
+   0x20, 0xE7, 0x03, 0x43, 0xF9, 0x08, 0x22, 0x00,
+/*0040*/0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x75,
+   0x51, 0x01, 0xE4, 0xF5, 0x52, 0xF5, 0x53, 0xF5,
+/*0050*/0x52, 0xF5, 0x7E, 0x7F, 0x04, 0x02, 0x04, 0x38,
+   0xC2, 0x36, 0x05, 0x52, 0xE5, 0x52, 0xD3, 0x94,
+/*0060*/0x0C, 0x40, 0x05, 0x75, 0x52, 0x01, 0xD2, 0x36,
+   0x90, 0x07, 0x0C, 0x74, 0x07, 0xF0, 0xA3, 0x74,
+/*0070*/0xFF, 0xF0, 0xE4, 0xF5, 0x0C, 0xA3, 0xF0, 0x90,
+   0x07, 0x14, 0xF0, 0xA3, 0xF0, 0x75, 0x0B, 0x20,
+/*0080*/0xF5, 0x09, 0xE4, 0xF5, 0x08, 0xE5, 0x08, 0xD3,
+   0x94, 0x30, 0x40, 0x03, 0x02, 0x04, 0x04, 0x12,
+/*0090*/0x00, 0x06, 0x15, 0x0B, 0xE5, 0x08, 0x70, 0x04,
+   0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x09,
+/*00A0*/0x70, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00,
+   0xEE, 0x5F, 0x60, 0x05, 0x12, 0x18, 0x71, 0xD2,
+/*00B0*/0x35, 0x53, 0xE1, 0xF7, 0xE5, 0x08, 0x45, 0x09,
+   0xFF, 0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24,
+/*00C0*/0x83, 0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83,
+   0xEF, 0xF0, 0x85, 0xE2, 0x20, 0xE5, 0x52, 0xD3,
+/*00D0*/0x94, 0x01, 0x40, 0x0D, 0x12, 0x19, 0xF3, 0xE0,
+   0x54, 0xA0, 0x64, 0x40, 0x70, 0x03, 0x02, 0x03,
+/*00E0*/0xFB, 0x53, 0xF9, 0xF8, 0x90, 0x94, 0x70, 0xE4,
+   0xF0, 0xE0, 0xF5, 0x10, 0xAF, 0x09, 0x12, 0x1E,
+/*00F0*/0xB3, 0xAF, 0x08, 0xEF, 0x44, 0x08, 0xF5, 0x82,
+   0x75, 0x83, 0x80, 0xE0, 0xF5, 0x29, 0xEF, 0x44,
+/*0100*/0x07, 0x12, 0x1A, 0x3C, 0xF5, 0x22, 0x54, 0x40,
+   0xD3, 0x94, 0x00, 0x40, 0x1E, 0xE5, 0x29, 0x54,
+/*0110*/0xF0, 0x70, 0x21, 0x12, 0x19, 0xF3, 0xE0, 0x44,
+   0x80, 0xF0, 0xE5, 0x22, 0x54, 0x30, 0x65, 0x08,
+/*0120*/0x70, 0x09, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xBF,
+   0xF0, 0x80, 0x09, 0x12, 0x19, 0xF3, 0x74, 0x40,
+/*0130*/0xF0, 0x02, 0x03, 0xFB, 0x12, 0x1A, 0x12, 0x75,
+   0x83, 0xAE, 0x74, 0xFF, 0xF0, 0xAF, 0x08, 0x7E,
+/*0140*/0x00, 0xEF, 0x44, 0x07, 0xF5, 0x82, 0xE0, 0xFD,
+   0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24, 0x81,
+/*0150*/0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83, 0xED,
+   0xF0, 0x90, 0x07, 0x0E, 0xE0, 0x04, 0xF0, 0xEF,
+/*0160*/0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0x98, 0xE0,
+   0xF5, 0x28, 0x12, 0x1A, 0x23, 0x40, 0x0C, 0x12,
+/*0170*/0x19, 0xF3, 0xE0, 0x44, 0x01, 0x12, 0x1A, 0x32,
+   0x02

[PATCH 37/53] IB/qib: Add qib_srq.c

2009-11-19 Thread Ralph Campbell
creates the qib_srq.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_srq.c |  374 +++
 1 files changed, 374 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_srq.c

diff --git a/drivers/infiniband/hw/qib/qib_srq.c 
b/drivers/infiniband/hw/qib/qib_srq.c
new file mode 100644
index 000..d79ae33
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_srq.c
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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/err.h
+#include linux/vmalloc.h
+
+#include qib_verbs.h
+
+/**
+ * qib_post_srq_receive - post a receive on a shared receive queue
+ * @ibsrq: the SRQ to post the receive on
+ * @wr: the list of work requests to post
+ * @bad_wr: A pointer to the first WR to cause a problem is put here
+ *
+ * This may be called from interrupt context.
+ */
+int qib_post_srq_receive(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
+struct ib_recv_wr **bad_wr)
+{
+   struct qib_srq *srq = to_isrq(ibsrq);
+   struct qib_rwq *wq;
+   unsigned long flags;
+   int ret;
+
+   for (; wr; wr = wr-next) {
+   struct qib_rwqe *wqe;
+   u32 next;
+   int i;
+
+   if ((unsigned) wr-num_sge  srq-rq.max_sge) {
+   *bad_wr = wr;
+   ret = -EINVAL;
+   goto bail;
+   }
+
+   spin_lock_irqsave(srq-rq.lock, flags);
+   wq = srq-rq.wq;
+   next = wq-head + 1;
+   if (next = srq-rq.size)
+   next = 0;
+   if (next == wq-tail) {
+   spin_unlock_irqrestore(srq-rq.lock, flags);
+   *bad_wr = wr;
+   ret = -ENOMEM;
+   goto bail;
+   }
+
+   wqe = get_rwqe_ptr(srq-rq, wq-head);
+   wqe-wr_id = wr-wr_id;
+   wqe-num_sge = wr-num_sge;
+   for (i = 0; i  wr-num_sge; i++)
+   wqe-sg_list[i] = wr-sg_list[i];
+   /* Make sure queue entry is written before the head index. */
+   smp_wmb();
+   wq-head = next;
+   spin_unlock_irqrestore(srq-rq.lock, flags);
+   }
+   ret = 0;
+
+bail:
+   return ret;
+}
+
+/**
+ * qib_create_srq - create a shared receive queue
+ * @ibpd: the protection domain of the SRQ to create
+ * @srq_init_attr: the attributes of the SRQ
+ * @udata: data from libibverbs when creating a user SRQ
+ */
+struct ib_srq *qib_create_srq(struct ib_pd *ibpd,
+ struct ib_srq_init_attr *srq_init_attr,
+ struct ib_udata *udata)
+{
+   struct qib_ibdev *dev = to_idev(ibpd-device);
+   struct qib_srq *srq;
+   u32 sz;
+   struct ib_srq *ret;
+
+   if (srq_init_attr-attr.max_sge == 0 ||
+   srq_init_attr-attr.max_sge  ib_qib_max_srq_sges ||
+   srq_init_attr-attr.max_wr == 0 ||
+   srq_init_attr-attr.max_wr  ib_qib_max_srq_wrs) {
+   ret = ERR_PTR(-EINVAL);
+   goto done;
+   }
+
+   srq = kmalloc(sizeof(*srq), GFP_KERNEL);
+   if (!srq) {
+   ret = ERR_PTR(-ENOMEM);
+   goto done;
+   }
+
+   /*
+* Need to use vmalloc() if we want to support large #s of entries.
+*/
+   srq-rq.size = srq_init_attr

[PATCH 38/53] IB/qib: Add qib_sysfs.c

2009-11-19 Thread Ralph Campbell
creates the qib_sysfs.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_sysfs.c |  736 +
 1 files changed, 736 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_sysfs.c

diff --git a/drivers/infiniband/hw/qib/qib_sysfs.c 
b/drivers/infiniband/hw/qib/qib_sysfs.c
new file mode 100644
index 000..747005a
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_sysfs.c
@@ -0,0 +1,736 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2006 PathScale, Inc. 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/ctype.h
+
+#include qib.h
+
+/**
+ * qib_parse_ushort - parse an unsigned short value in an arbitrary base
+ * @str: the string containing the number
+ * @valp: where to put the result
+ *
+ * Returns the number of bytes consumed, or negative value on error.
+ */
+static int qib_parse_ushort(const char *str, unsigned short *valp)
+{
+   unsigned long val;
+   char *end;
+   int ret;
+
+   if (!isdigit(str[0])) {
+   ret = -EINVAL;
+   goto bail;
+   }
+
+   val = simple_strtoul(str, end, 0);
+
+   if (val  0x) {
+   ret = -EINVAL;
+   goto bail;
+   }
+
+   *valp = val;
+
+   ret = end + 1 - str;
+   if (ret == 0)
+   ret = -EINVAL;
+
+bail:
+   return ret;
+}
+
+/* start of per-port functions */
+/*
+ * Get/Set heartbeat enable. OR of 1=enabled, 2=auto
+ */
+static ssize_t show_hrtbt_enb(struct qib_pportdata *ppd, char *buf)
+{
+   struct qib_devdata *dd = ppd-dd;
+   int ret;
+
+   ret = dd-f_get_ib_cfg(ppd, QIB_IB_CFG_HRTBT);
+   ret = scnprintf(buf, PAGE_SIZE, %d\n, ret);
+   return ret;
+}
+
+static ssize_t store_hrtbt_enb(struct qib_pportdata *ppd, const char *buf,
+  size_t count)
+{
+   struct qib_devdata *dd = ppd-dd;
+   int ret;
+   u16 val;
+
+   ret = qib_parse_ushort(buf, val);
+
+   /*
+* Set the intentional heartbeat enable per either of
+* Enable and Auto, as these are normally set together.
+* This bit is consulted when leaving loopback mode,
+* because entering loopback mode overrides it and automatically
+* disables heartbeat.
+*/
+   if (ret = 0)
+   ret = dd-f_set_ib_cfg(ppd, QIB_IB_CFG_HRTBT, val);
+   if (ret  0)
+   qib_dev_err(dd, attempt to set invalid Heartbeat enable\n);
+   return ret  0 ? ret : count;
+}
+
+static ssize_t store_loopback(struct qib_pportdata *ppd, const char *buf,
+ size_t count)
+{
+   struct qib_devdata *dd = ppd-dd;
+   int ret = count, r;
+
+   r = dd-f_set_ib_loopback(ppd, buf);
+   if (r  0)
+   ret = r;
+
+   return ret;
+}
+
+static ssize_t store_led_override(struct qib_pportdata *ppd, const char *buf,
+ size_t count)
+{
+   struct qib_devdata *dd = ppd-dd;
+   int ret;
+   u16 val;
+
+   ret = qib_parse_ushort(buf, val);
+   if (ret  0)
+   qib_set_led_override(ppd, val);
+   else
+   qib_dev_err(dd, attempt to set invalid LED override\n);
+   return ret  0 ? ret : count;
+}
+
+static ssize_t show_qsfp(struct qib_pportdata *ppd, char *buf)
+{
+   ssize_t ret;
+
+   ret = qib_qsfp_dump(ppd, buf, PAGE_SIZE);
+   return ret;
+}
+
+static ssize_t show_status(struct qib_pportdata *ppd, char *buf)
+{
+   ssize_t ret

[PATCH 40/53] IB/qib: Add qib_trace.h

2009-11-19 Thread Ralph Campbell
creates the qib_trace.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_trace.h |   65 +
 1 files changed, 65 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_trace.h

diff --git a/drivers/infiniband/hw/qib/qib_trace.h 
b/drivers/infiniband/hw/qib/qib_trace.h
new file mode 100644
index 000..880168e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_trace.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. 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.
+ */
+
+#ifndef _QIB_TRACE_H
+#define _QIB_TRACE_H
+
+struct qib_evt_buf;
+
+extern struct qib_evt_buf *qib_trace_buf;
+
+void qib_trace_put8(struct qib_evt_buf *buf,
+  int cpu, u64 tsc, u32 dbgmask, u8);
+
+void qib_trace_put16(struct qib_evt_buf *buf,
+int cpu, u64 tsc, u32 dbgmask, u16);
+
+void qib_trace_put32(struct qib_evt_buf *buf,
+int cpu, u64 tsc, u32 dbgmask, u32 val);
+
+void qib_trace_put64(struct qib_evt_buf *buf,
+int cpu, u64 tsc, u32 dbgmask, u64 val);
+
+void qib_trace_putblob(struct qib_evt_buf *buf,
+  int cpu, u64 tsc, u32 dbgmask, void *blob, u16 len);
+
+void qib_trace_putstr(struct qib_evt_buf *buf,
+ int cpu, u64 tsc, u32 dbgmask, const char *str);
+
+void qib_trace_vputstr(struct qib_evt_buf *buf,
+  int cpu, u64 tsc, u32 dbgmask, const char *fmt, ...)
+  __attribute__ ((format (printf, 5, 6)));
+
+int __init qib_trace_init(void);
+void qib_trace_fini(void);
+
+#endif

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 39/53] IB/qib: Add qib_trace.c

2009-11-19 Thread Ralph Campbell
creates the qib_trace.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_trace.c | 1346 +
 1 files changed, 1346 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_trace.c

diff --git a/drivers/infiniband/hw/qib/qib_trace.c 
b/drivers/infiniband/hw/qib/qib_trace.c
new file mode 100644
index 000..9df230a
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_trace.c
@@ -0,0 +1,1346 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. 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/module.h
+#include linux/fs.h
+#include linux/cdev.h
+#include linux/device.h
+#include linux/hardirq.h
+#include linux/spinlock.h
+#include linux/sched.h
+#include linux/wait.h
+#include linux/vmalloc.h
+#include linux/uaccess.h
+#include linux/notifier.h
+
+#include qib.h
+
+#define QIB_TRACE_FILE ipath_trace
+#define QIB_TRACE_MAXCACHENAME 32
+
+enum qib_trace_cmd_type {
+   IPATH_TRACE_CLEAR = 0,
+   IPATH_TRACE_RESTART,
+   IPATH_TRACE_DUMP,
+   IPATH_TRACE_DUMP_AND_CLEAR,
+   IPATH_TRACE_GETSIZE,
+   IPATH_TRACE_INJECT
+};
+
+enum qib_evt_type {
+   QIB_EVT_NONE = 0,
+   QIB_EVT_U8,
+   QIB_EVT_U16,
+   QIB_EVT_U32,
+   QIB_EVT_U64,
+   QIB_EVT_STR,
+   QIB_EVT_BLOB,
+   QIB_EVT_EMPTY
+};
+
+enum qib_evt_blobtype {
+   QIB_EVT_BLOB_QP = 0,
+   QIB_EVT_BLOB_CQ,
+   QIB_EVT_BLOB_SRQ
+};
+
+struct qib_trace_cmd {
+   enum qib_trace_cmd_type type;
+
+   union {
+   /* event cursor where we should restart from */
+   unsigned int cursor;
+
+   /* user address for storing the size of the trace buffer */
+   struct {
+   unsigned int __user *bufsize;
+   unsigned int __user *blobsize;
+   };
+
+   struct {
+   void __user *buf;
+   unsigned int size;
+   };
+   };
+};
+
+struct qib_evt_val {
+   enum qib_evt_type type;
+   size_t len;
+
+   union {
+   u8  d8;
+   u16 d16;
+   u32 d32;
+   u64 d64;
+   const void *blob;
+   };
+};
+
+/*
+ * Event holder
+ */
+struct qib_evt {
+   u64 tsc;
+   u32 dbgmask;
+   u16 len;
+   u16 cpu_type;
+   u64 id;
+   u64 data[0];
+};
+
+struct qib_evt_container {
+   atomic_t refcnt;
+
+   /* needs to be at the end of the struct as blob data is inlined here */
+   struct qib_evt evt;
+};
+
+static inline void qib_evt_settsc(struct qib_evt *evt, u64 tsc)
+{
+   evt-tsc = tsc;
+}
+
+static inline void qib_evt_setdbgmask(struct qib_evt *evt, u32 dbgmask)
+{
+   evt-dbgmask = dbgmask;
+}
+
+static inline void qib_evt_setlen(struct qib_evt *evt, u16 len)
+{
+   evt-len = len;
+}
+
+static inline void qib_evt_setcpu(struct qib_evt *evt, int cpu)
+{
+   evt-cpu_type = (evt-cpu_type  0xff) | ((cpu  0xff)  8);
+}
+
+static inline void qib_evt_setblobtype(struct qib_evt *evt,
+  enum qib_evt_blobtype bt)
+{
+   evt-cpu_type = (evt-cpu_type  0xff07) | ((bt  0x1f)  3);
+}
+
+static inline void qib_evt_settype(struct qib_evt *evt, enum qib_evt_type type)
+{
+   evt-cpu_type = (evt-cpu_type  0xfff8) | (type  0x7);
+}
+
+static inline void qib_evt_setid(struct qib_evt *evt, u64 id)
+{
+   evt-id = id;
+}
+
+static inline u64 qib_evt_gettsc(struct qib_evt *evt)
+{
+   return evt-tsc;
+}
+
+static inline u32

[PATCH 43/53] IB/qib: Add qib_uc.c

2009-11-19 Thread Ralph Campbell
creates the qib_uc.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_uc.c |  586 
 1 files changed, 586 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_uc.c

diff --git a/drivers/infiniband/hw/qib/qib_uc.c 
b/drivers/infiniband/hw/qib/qib_uc.c
new file mode 100644
index 000..f077489
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_uc.c
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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 qib.h
+
+/* cut down ridiculously long IB macro names */
+#define OP(x) IB_OPCODE_UC_##x
+
+/**
+ * qib_make_uc_req - construct a request packet (SEND, RDMA write)
+ * @qp: a pointer to the QP
+ *
+ * Return 1 if constructed; otherwise, return 0.
+ */
+int qib_make_uc_req(struct qib_qp *qp)
+{
+   struct qib_other_headers *ohdr;
+   struct qib_swqe *wqe;
+   unsigned long flags;
+   u32 hwords;
+   u32 bth0;
+   u32 len;
+   u32 pmtu = ib_mtu_enum_to_int(qp-path_mtu);
+   int ret = 0;
+
+   spin_lock_irqsave(qp-s_lock, flags);
+
+   if (!(ib_qib_state_ops[qp-state]  QIB_PROCESS_SEND_OK)) {
+   if (!(ib_qib_state_ops[qp-state]  QIB_FLUSH_SEND))
+   goto bail;
+   /* We are in the error state, flush the work request. */
+   if (qp-s_last == qp-s_head)
+   goto bail;
+   /* If DMAs are in progress, we can't flush immediately. */
+   if (atomic_read(qp-s_dma_busy)) {
+   qp-s_flags |= QIB_S_WAIT_DMA;
+   goto bail;
+   }
+   wqe = get_swqe_ptr(qp, qp-s_last);
+   qib_send_complete(qp, wqe, IB_WC_WR_FLUSH_ERR);
+   goto done;
+   }
+
+   ohdr = qp-s_hdr.u.oth;
+   if (qp-remote_ah_attr.ah_flags  IB_AH_GRH)
+   ohdr = qp-s_hdr.u.l.oth;
+
+   /* header size in 32-bit words LRH+BTH = (8+12)/4. */
+   hwords = 5;
+   bth0 = 1  22; /* Set M bit */
+
+   /* Get the next send request. */
+   wqe = get_swqe_ptr(qp, qp-s_cur);
+   qp-s_wqe = NULL;
+   switch (qp-s_state) {
+   default:
+   if (!(ib_qib_state_ops[qp-state] 
+   QIB_PROCESS_NEXT_SEND_OK))
+   goto bail;
+   /* Check if send work queue is empty. */
+   if (qp-s_cur == qp-s_head)
+   goto bail;
+   /*
+* Start a new request.
+*/
+   wqe-psn = qp-s_next_psn;
+   qp-s_psn = qp-s_next_psn;
+   qp-s_sge.sge = wqe-sg_list[0];
+   qp-s_sge.sg_list = wqe-sg_list + 1;
+   qp-s_sge.num_sge = wqe-wr.num_sge;
+   qp-s_sge.total_len = wqe-length;
+   len = wqe-length;
+   qp-s_len = len;
+   switch (wqe-wr.opcode) {
+   case IB_WR_SEND:
+   case IB_WR_SEND_WITH_IMM:
+   if (len  pmtu) {
+   qp-s_state = OP(SEND_FIRST);
+   len = pmtu;
+   break;
+   }
+   if (wqe-wr.opcode == IB_WR_SEND)
+   qp-s_state = OP(SEND_ONLY);
+   else {
+   qp-s_state =
+   OP(SEND_ONLY_WITH_IMMEDIATE

[PATCH 44/53] IB/qib: Add qib_ud.c

2009-11-19 Thread Ralph Campbell
creates the qib_ud.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_ud.c |  607 
 1 files changed, 607 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_ud.c

diff --git a/drivers/infiniband/hw/qib/qib_ud.c 
b/drivers/infiniband/hw/qib/qib_ud.c
new file mode 100644
index 000..c838cda
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_ud.c
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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 rdma/ib_smi.h
+
+#include qib.h
+#include qib_mad.h
+
+/**
+ * qib_ud_loopback - handle send on loopback QPs
+ * @sqp: the sending QP
+ * @swqe: the send work request
+ *
+ * This is called from qib_make_ud_req() to forward a WQE addressed
+ * to the same HCA.
+ * Note that the receive interrupt handler may be calling qib_ud_rcv()
+ * while this is being called.
+ */
+static void qib_ud_loopback(struct qib_qp *sqp, struct qib_swqe *swqe)
+{
+   struct qib_ibport *ibp = to_iport(sqp-ibqp.device, sqp-port_num);
+   struct qib_pportdata *ppd;
+   struct qib_qp *qp;
+   struct ib_ah_attr *ah_attr;
+   unsigned long flags;
+   struct qib_sge_state ssge;
+   struct qib_sge *sge;
+   struct ib_wc wc;
+   u32 length;
+
+   qp = qib_lookup_qpn(ibp, swqe-wr.wr.ud.remote_qpn);
+   if (!qp) {
+   ibp-n_pkt_drops++;
+   return;
+   }
+   if (qp-ibqp.qp_type != sqp-ibqp.qp_type ||
+   !(ib_qib_state_ops[qp-state]  QIB_PROCESS_RECV_OK)) {
+   ibp-n_pkt_drops++;
+   goto drop;
+   }
+
+   ah_attr = to_iah(swqe-wr.wr.ud.ah)-attr;
+   ppd = ppd_from_ibp(ibp);
+
+   if (qp-ibqp.qp_num  1) {
+   u16 pkey1;
+   u16 pkey2;
+   u16 lid;
+
+   pkey1 = qib_get_pkey(ibp, sqp-s_pkey_index);
+   pkey2 = qib_get_pkey(ibp, qp-s_pkey_index);
+   if (unlikely(!qib_pkey_ok(pkey1, pkey2))) {
+   lid = ppd-lid | (ah_attr-src_path_bits 
+ ((1  ppd-lmc) - 1));
+   qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_PKEY, pkey1,
+ ah_attr-sl,
+ sqp-ibqp.qp_num, qp-ibqp.qp_num,
+ cpu_to_be16(lid),
+ cpu_to_be16(ah_attr-dlid));
+   goto drop;
+   }
+   }
+
+   /*
+* Check that the qkey matches (except for QP0, see 9.6.1.4.1).
+* Qkeys with the high order bit set mean use the
+* qkey from the QP context instead of the WR (see 10.2.5).
+*/
+   if (qp-ibqp.qp_num) {
+   u32 qkey;
+
+   qkey = (int)swqe-wr.wr.ud.remote_qkey  0 ?
+   sqp-qkey : swqe-wr.wr.ud.remote_qkey;
+   if (unlikely(qkey != qp-qkey)) {
+   u16 lid;
+
+   lid = ppd-lid | (ah_attr-src_path_bits 
+ ((1  ppd-lmc) - 1));
+   qib_bad_pqkey(ibp, IB_NOTICE_TRAP_BAD_QKEY, qkey,
+ ah_attr-sl,
+ sqp-ibqp.qp_num, qp-ibqp.qp_num,
+ cpu_to_be16(lid),
+ cpu_to_be16(ah_attr-dlid));
+   goto drop

[PATCH 42/53] IB/qib: Add qib_tx.c

2009-11-19 Thread Ralph Campbell
creates the qib_tx.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_tx.c |  585 
 1 files changed, 585 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_tx.c

diff --git a/drivers/infiniband/hw/qib/qib_tx.c 
b/drivers/infiniband/hw/qib/qib_tx.c
new file mode 100644
index 000..7d77f29
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_tx.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (c) 2008, 2009 QLogic Corporation. 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/spinlock.h
+#include linux/pci.h
+#include linux/io.h
+#include linux/delay.h
+#include linux/netdevice.h
+#include linux/vmalloc.h
+
+#include qib.h
+
+static unsigned qib_hol_timeout_ms = 3000;
+module_param_named(hol_timeout_ms, qib_hol_timeout_ms, uint, S_IRUGO);
+MODULE_PARM_DESC(hol_timeout_ms,
+duration of user app suspension after link failure);
+
+unsigned qib_sdma_fetch_arb = 1;
+module_param_named(fetch_arb, qib_sdma_fetch_arb, uint, S_IRUGO);
+MODULE_PARM_DESC(fetch_arb, IBA7220: change SDMA descriptor arbitration);
+
+/**
+ * qib_disarm_piobufs - cancel a range of PIO buffers
+ * @dd: the qlogic_ib device
+ * @first: the first PIO buffer to cancel
+ * @cnt: the number of PIO buffers to cancel
+ *
+ * Cancel a range of PIO buffers. Used at user process close,
+ * in case it died while writing to a PIO buffer.
+ */
+void qib_disarm_piobufs(struct qib_devdata *dd, unsigned first, unsigned cnt)
+{
+   unsigned long flags;
+   unsigned i;
+   unsigned last;
+
+   qib_cdbg(ERRPKT, disarm %u PIObufs first=%u\n, cnt, first);
+   last = first + cnt;
+   spin_lock_irqsave(dd-pioavail_lock, flags);
+   for (i = first; i  last; i++) {
+   __clear_bit(i, dd-pio_need_disarm);
+   dd-f_sendctrl(dd-pport, QIB_SENDCTRL_DISARM_BUF(i));
+   }
+   spin_unlock_irqrestore(dd-pioavail_lock, flags);
+}
+
+/*
+ * This is called by a user process when it sees the DISARM_BUFS event
+ * bit is set.
+ */
+int qib_disarm_piobufs_ifneeded(struct qib_ctxtdata *rcd)
+{
+   struct qib_devdata *dd = rcd-dd;
+   unsigned i;
+   unsigned last;
+   unsigned n = 0;
+
+   last = rcd-pio_base + rcd-piocnt;
+   /*
+* Don't need uctxt_lock here, since user has called in to us.
+* Clear at start in case more interrupts set bits while we
+* are disarming
+*/
+   if (rcd-user_event_mask) {
+   /*
+* subctxt_cnt is 0 if not shared, so do base
+* separately, first, then remaining subctxt, if any
+*/
+   clear_bit(_QIB_EVENT_DISARM_BUFS_BIT, rcd-user_event_mask[0]);
+   for (i = 1; i  rcd-subctxt_cnt; i++)
+   clear_bit(_QIB_EVENT_DISARM_BUFS_BIT,
+ rcd-user_event_mask[i]);
+   }
+   spin_lock_irq(dd-pioavail_lock);
+   for (i = rcd-pio_base; i  last; i++) {
+   if (__test_and_clear_bit(i, dd-pio_need_disarm)) {
+   n++;
+   dd-f_sendctrl(rcd-ppd, QIB_SENDCTRL_DISARM_BUF(i));
+   }
+   }
+   spin_unlock_irq(dd-pioavail_lock);
+   qib_cdbg(ERRPKT, Ctxt%u, User disarm (%u bufs (%u-%u)) done\n,
+   rcd-ctxt, n, rcd-pio_base, last);
+   return 0;
+}
+
+static struct qib_pportdata *is_sdma_buf(struct qib_devdata *dd, unsigned i)
+{
+   struct qib_pportdata *ppd;
+   unsigned pidx;
+
+   for (pidx = 0; pidx  dd-num_pports; pidx

[PATCH 45/53] IB/qib: Add qib_user_pages.c

2009-11-19 Thread Ralph Campbell
creates the qib_user_pages.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_user_pages.c |  163 
 1 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_user_pages.c

diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c 
b/drivers/infiniband/hw/qib/qib_user_pages.c
new file mode 100644
index 000..a0406a2
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_user_pages.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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/mm.h
+#include linux/device.h
+
+#include qib.h
+
+static void __qib_release_user_pages(struct page **p, size_t num_pages,
+int dirty)
+{
+   size_t i;
+
+   for (i = 0; i  num_pages; i++) {
+   qib_cdbg(MM, %lu/%lu put_page %p\n, (unsigned long) i,
+(unsigned long) num_pages, p[i]);
+   if (dirty)
+   set_page_dirty_lock(p[i]);
+   put_page(p[i]);
+   }
+}
+
+/*
+ * Call with current-mm-mmap_sem held.
+ */
+static int __get_user_pages(unsigned long start_page, size_t num_pages,
+   struct page **p, struct vm_area_struct **vma)
+{
+   unsigned long lock_limit;
+   size_t got;
+   int ret;
+
+   lock_limit = current-signal-rlim[RLIMIT_MEMLOCK].rlim_cur 
+   PAGE_SHIFT;
+
+   if (num_pages  lock_limit) {
+   ret = -ENOMEM;
+   goto bail;
+   }
+
+   qib_cdbg(VERBOSE, pin %lx pages from vaddr %lx\n,
+(unsigned long) num_pages, start_page);
+
+   for (got = 0; got  num_pages; got += ret) {
+   ret = get_user_pages(current, current-mm,
+start_page + got * PAGE_SIZE,
+num_pages - got, 1, 1,
+p + got, vma);
+   if (ret  0)
+   goto bail_release;
+   }
+
+   current-mm-locked_vm += num_pages;
+
+   ret = 0;
+   goto bail;
+
+bail_release:
+   __qib_release_user_pages(p, got, 0);
+bail:
+   return ret;
+}
+
+/**
+ * qib_map_page - a safety wrapper around pci_map_page()
+ *
+ * A dma_addr of all 0's is interpreted by the chip as disabled.
+ * Unfortunately, it can also be a valid dma_addr returned on some
+ * architectures.
+ *
+ * The powerpc iommu assigns dma_addrs in ascending order, so we don't
+ * have to bother with retries or mapping a dummy page to insure we
+ * don't just get the same mapping again.
+ *
+ * I'm sure we won't be so lucky with other iommu's, so FIXME.
+ */
+dma_addr_t qib_map_page(struct pci_dev *hwdev, struct page *page,
+   unsigned long offset, size_t size, int direction)
+{
+   dma_addr_t phys;
+
+   phys = pci_map_page(hwdev, page, offset, size, direction);
+
+   if (phys == 0) {
+   pci_unmap_page(hwdev, phys, size, direction);
+   phys = pci_map_page(hwdev, page, offset, size, direction);
+   /*
+* FIXME: If we get 0 again, we should keep this page,
+* map another, then free the 0 page.
+*/
+   }
+
+   return phys;
+}
+
+/**
+ * qib_get_user_pages - lock user pages into memory
+ * @start_page: the start page
+ * @num_pages: the number of pages
+ * @p: the output page structures
+ *
+ * This function takes

[PATCH 47/53] IB/qib: Add qib_user_sdma.h

2009-11-19 Thread Ralph Campbell
creates the qib_user_sdma.h file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_user_sdma.h |   52 +
 1 files changed, 52 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_user_sdma.h

diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.h 
b/drivers/infiniband/hw/qib/qib_user_sdma.h
new file mode 100644
index 000..ce8cbaf
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_user_sdma.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 2008 QLogic Corporation. 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/device.h
+
+struct qib_user_sdma_queue;
+
+struct qib_user_sdma_queue *
+qib_user_sdma_queue_create(struct device *dev, int unit, int port, int sport);
+void qib_user_sdma_queue_destroy(struct qib_user_sdma_queue *pq);
+
+int qib_user_sdma_writev(struct qib_ctxtdata *pd,
+struct qib_user_sdma_queue *pq,
+const struct iovec *iov,
+unsigned long dim);
+
+int qib_user_sdma_make_progress(struct qib_pportdata *ppd,
+   struct qib_user_sdma_queue *pq);
+
+void qib_user_sdma_queue_drain(struct qib_pportdata *ppd,
+  struct qib_user_sdma_queue *pq);
+
+u32 qib_user_sdma_complete_counter(const struct qib_user_sdma_queue *pq);
+u32 qib_user_sdma_inflight_counter(struct qib_user_sdma_queue *pq);

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 50/53] IB/qib: Add qib_verbs_mcast.c

2009-11-19 Thread Ralph Campbell
creates the qib_verbs_mcast.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_verbs_mcast.c |  368 +++
 1 files changed, 368 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_verbs_mcast.c

diff --git a/drivers/infiniband/hw/qib/qib_verbs_mcast.c 
b/drivers/infiniband/hw/qib/qib_verbs_mcast.c
new file mode 100644
index 000..dabb697
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_verbs_mcast.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2005, 2006 PathScale, Inc. 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/rculist.h
+
+#include qib.h
+
+/**
+ * qib_mcast_qp_alloc - alloc a struct to link a QP to mcast GID struct
+ * @qp: the QP to link
+ */
+static struct qib_mcast_qp *qib_mcast_qp_alloc(struct qib_qp *qp)
+{
+   struct qib_mcast_qp *mqp;
+
+   mqp = kmalloc(sizeof *mqp, GFP_KERNEL);
+   if (!mqp)
+   goto bail;
+
+   mqp-qp = qp;
+   atomic_inc(qp-refcount);
+
+bail:
+   return mqp;
+}
+
+static void qib_mcast_qp_free(struct qib_mcast_qp *mqp)
+{
+   struct qib_qp *qp = mqp-qp;
+
+   /* Notify qib_destroy_qp() if it is waiting. */
+   if (atomic_dec_and_test(qp-refcount))
+   wake_up(qp-wait);
+
+   kfree(mqp);
+}
+
+/**
+ * qib_mcast_alloc - allocate the multicast GID structure
+ * @mgid: the multicast GID
+ *
+ * A list of QPs will be attached to this structure.
+ */
+static struct qib_mcast *qib_mcast_alloc(union ib_gid *mgid)
+{
+   struct qib_mcast *mcast;
+
+   mcast = kmalloc(sizeof *mcast, GFP_KERNEL);
+   if (!mcast)
+   goto bail;
+
+   mcast-mgid = *mgid;
+   INIT_LIST_HEAD(mcast-qp_list);
+   init_waitqueue_head(mcast-wait);
+   atomic_set(mcast-refcount, 0);
+   mcast-n_attached = 0;
+
+bail:
+   return mcast;
+}
+
+static void qib_mcast_free(struct qib_mcast *mcast)
+{
+   struct qib_mcast_qp *p, *tmp;
+
+   list_for_each_entry_safe(p, tmp, mcast-qp_list, list)
+   qib_mcast_qp_free(p);
+
+   kfree(mcast);
+}
+
+/**
+ * qib_mcast_find - search the global table for the given multicast GID
+ * @ibp: the IB port structure
+ * @mgid: the multicast GID to search for
+ *
+ * Returns NULL if not found.
+ *
+ * The caller is responsible for decrementing the reference count if found.
+ */
+struct qib_mcast *qib_mcast_find(struct qib_ibport *ibp, union ib_gid *mgid)
+{
+   struct rb_node *n;
+   unsigned long flags;
+   struct qib_mcast *mcast;
+
+   spin_lock_irqsave(ibp-lock, flags);
+   n = ibp-mcast_tree.rb_node;
+   while (n) {
+   int ret;
+
+   mcast = rb_entry(n, struct qib_mcast, rb_node);
+
+   ret = memcmp(mgid-raw, mcast-mgid.raw,
+sizeof(union ib_gid));
+   if (ret  0)
+   n = n-rb_left;
+   else if (ret  0)
+   n = n-rb_right;
+   else {
+   atomic_inc(mcast-refcount);
+   spin_unlock_irqrestore(ibp-lock, flags);
+   goto bail;
+   }
+   }
+   spin_unlock_irqrestore(ibp-lock, flags);
+
+   mcast = NULL;
+
+bail:
+   return mcast;
+}
+
+/**
+ * qib_mcast_add - insert mcast GID into table and attach QP struct
+ * @mcast: the mcast GID table
+ * @mqp: the QP to attach
+ *
+ * Return zero if both were added.  Return EEXIST if the GID was already in
+ * the table

[PATCH 51/53] IB/qib: Add qib_wc_ppc64.c

2009-11-19 Thread Ralph Campbell
creates the qib_wc_ppc64.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_wc_ppc64.c |   62 ++
 1 files changed, 62 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_wc_ppc64.c

diff --git a/drivers/infiniband/hw/qib/qib_wc_ppc64.c 
b/drivers/infiniband/hw/qib/qib_wc_ppc64.c
new file mode 100644
index 000..673cf4c
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_wc_ppc64.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2006, 2007, 2008 QLogic Corporation. 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.
+ */
+
+/*
+ * This file is conditionally built on PowerPC only.  Otherwise weak symbol
+ * versions of the functions exported from here are used.
+ */
+
+#include qib.h
+
+/**
+ * qib_enable_wc - enable write combining for MMIO writes to the device
+ * @dd: qlogic_ib device
+ *
+ * Nothing to do on PowerPC, so just return without error.
+ */
+int qib_enable_wc(struct qib_devdata *dd)
+{
+   return 0;
+}
+
+/**
+ * qib_unordered_wc - indicate whether write combining is unordered
+ *
+ * Because our performance depends on our ability to do write
+ * combining mmio writes in the most efficient way, we need to
+ * know if we are on a processor that may reorder stores when
+ * write combining.
+ */
+int qib_unordered_wc(void)
+{
+   return 1;
+}

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 52/53] IB/qib: Add qib_wc_x86_64.c

2009-11-19 Thread Ralph Campbell
creates the qib_wc_x86_64.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_wc_x86_64.c |  187 +
 1 files changed, 187 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_wc_x86_64.c

diff --git a/drivers/infiniband/hw/qib/qib_wc_x86_64.c 
b/drivers/infiniband/hw/qib/qib_wc_x86_64.c
new file mode 100644
index 000..594c198
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_wc_x86_64.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights 
reserved.
+ * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. 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.
+ */
+
+/*
+ * This file is conditionally built on x86_64 only.  Otherwise weak symbol
+ * versions of the functions exported from here are used.
+ */
+
+#include linux/pci.h
+#include asm/mtrr.h
+#include asm/processor.h
+
+#include qib.h
+
+/**
+ * qib_enable_wc - enable write combining for MMIO writes to the device
+ * @dd: qlogic_ib device
+ *
+ * This routine is x86_64-specific; it twiddles the CPU's MTRRs to enable
+ * write combining.
+ */
+int qib_enable_wc(struct qib_devdata *dd)
+{
+   int ret = 0;
+   u64 pioaddr, piolen;
+   unsigned bits;
+   const unsigned long addr = pci_resource_start(dd-pcidev, 0);
+   const size_t len = pci_resource_len(dd-pcidev, 0);
+
+   /*
+* Set the PIO buffers to be WCCOMB, so we get HT bursts to the
+* chip.  Linux (possibly the hardware) requires it to be on a power
+* of 2 address matching the length (which has to be a power of 2).
+* For rev1, that means the base address, for rev2, it will be just
+* the PIO buffers themselves.
+* For chips with two sets of buffers, the calculations are
+* somewhat more complicated; we need to sum, and the piobufbase
+* register has both offsets, 2K in low 32 bits, 4K in high 32 bits.
+* The buffers are still packed, so a single range covers both.
+*/
+   if (dd-piobcnt2k  dd-piobcnt4k) {
+   /* 2 sizes for chip */
+   unsigned long pio2kbase, pio4kbase;
+   pio2kbase = dd-piobufbase  0xUL;
+   pio4kbase = (dd-piobufbase  32)  0xUL;
+   if (pio2kbase  pio4kbase) {
+   /* all current chips */
+   pioaddr = addr + pio2kbase;
+   piolen = pio4kbase - pio2kbase +
+   dd-piobcnt4k * dd-align4k;
+   } else {
+   pioaddr = addr + pio4kbase;
+   piolen = pio2kbase - pio4kbase +
+   dd-piobcnt2k * dd-palign;
+   }
+   } else {  /* single buffer size (2K, currently) */
+   pioaddr = addr + dd-piobufbase;
+   piolen = dd-piobcnt2k * dd-palign +
+   dd-piobcnt4k * dd-align4k;
+   }
+
+   for (bits = 0; !(piolen  (1ULL  bits)); bits++)
+   /* do nothing */ ;
+
+   if (piolen != (1ULL  bits)) {
+   piolen = bits;
+   while (piolen = 1)
+   bits++;
+   piolen = 1ULL  (bits + 1);
+   }
+   if (pioaddr  (piolen - 1)) {
+   u64 atmp;
+   qib_dbg(pioaddr %llx not on right boundary for size 
+ %llx, fixing\n,
+ (unsigned long long) pioaddr,
+ (unsigned long long) piolen);
+   atmp = pioaddr  ~(piolen - 1

[PATCH 53/53] IB/qib: Hooks for adding the QIB driver into the framework

2009-11-19 Thread Ralph Campbell
Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/Kconfig  |1 +
 drivers/infiniband/Makefile |1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index dd0db67..c80f973 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -42,6 +42,7 @@ config INFINIBAND_ADDR_TRANS
 
 source drivers/infiniband/hw/mthca/Kconfig
 source drivers/infiniband/hw/ipath/Kconfig
+source drivers/infiniband/hw/qib/Kconfig
 source drivers/infiniband/hw/ehca/Kconfig
 source drivers/infiniband/hw/amso1100/Kconfig
 source drivers/infiniband/hw/cxgb3/Kconfig
diff --git a/drivers/infiniband/Makefile b/drivers/infiniband/Makefile
index ed35e44..27b66b1 100644
--- a/drivers/infiniband/Makefile
+++ b/drivers/infiniband/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_INFINIBAND)   += core/
 obj-$(CONFIG_INFINIBAND_MTHCA) += hw/mthca/
 obj-$(CONFIG_INFINIBAND_IPATH) += hw/ipath/
+obj-$(CONFIG_INFINIBAND_QIB)   += hw/qib/
 obj-$(CONFIG_INFINIBAND_EHCA)  += hw/ehca/
 obj-$(CONFIG_INFINIBAND_AMSO1100)  += hw/amso1100/
 obj-$(CONFIG_INFINIBAND_CXGB3) += hw/cxgb3/

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 46/53] IB/qib: Add qib_user_sdma.c

2009-11-19 Thread Ralph Campbell
creates the qib_user_sdma.c file.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

 drivers/infiniband/hw/qib/qib_user_sdma.c |  909 +
 1 files changed, 909 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/hw/qib/qib_user_sdma.c

diff --git a/drivers/infiniband/hw/qib/qib_user_sdma.c 
b/drivers/infiniband/hw/qib/qib_user_sdma.c
new file mode 100644
index 000..869244e
--- /dev/null
+++ b/drivers/infiniband/hw/qib/qib_user_sdma.c
@@ -0,0 +1,909 @@
+/*
+ * Copyright (c) 2007, 2008, 2009 QLogic Corporation. 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/mm.h
+#include linux/types.h
+#include linux/device.h
+#include linux/dmapool.h
+#include linux/slab.h
+#include linux/list.h
+#include linux/highmem.h
+#include linux/io.h
+#include linux/uio.h
+#include linux/rbtree.h
+#include linux/spinlock.h
+#include linux/delay.h
+
+#include qib.h
+#include qib_user_sdma.h
+
+/* minimum size of header */
+#define QIB_USER_SDMA_MIN_HEADER_LENGTH 64
+/* expected size of headers (for dma_pool) */
+#define QIB_USER_SDMA_EXP_HEADER_LENGTH 64
+
+struct qib_user_sdma_pkt {
+   u8 naddr;   /* dimension of addr (1..3) ... */
+   u32 counter;/* sdma pkts queued counter for this entry */
+   u64 added;  /* global descq number of entries */
+
+   struct {
+   u32 offset; /* offset for kvaddr, addr */
+   u32 length; /* length in page */
+   u8  put_page;   /* should we put_page? */
+   u8  dma_mapped; /* is page dma_mapped? */
+   struct page *page;  /* may be NULL (coherent mem) */
+   void *kvaddr;   /* FIXME: only for pio hack */
+   dma_addr_t addr;
+   } addr[4];   /* max pages, any more and we coalesce */
+   struct list_head list;  /* list element */
+};
+
+struct qib_user_sdma_queue {
+   /*
+* pkts sent to dma engine are queued on this
+* list head.  the type of the elements of this
+* list are struct qib_user_sdma_pkt...
+*/
+   struct list_head sent;
+
+   /* headers with expected length are allocated from here... */
+   char header_cache_name[64];
+   struct dma_pool *header_cache;
+
+   /* packets are allocated from the slab cache... */
+   char pkt_slab_name[64];
+   struct kmem_cache *pkt_slab;
+
+   /* as packets go on the queued queue, they are counted... */
+   u32 counter;
+   u32 sent_counter;
+
+   /* dma page table */
+   struct rb_root dma_pages_root;
+
+   /* protect everything above... */
+   struct mutex lock;
+};
+
+struct qib_user_sdma_queue *
+qib_user_sdma_queue_create(struct device *dev, int unit, int ctxt, int sctxt)
+{
+   struct qib_user_sdma_queue *pq =
+   kmalloc(sizeof(struct qib_user_sdma_queue), GFP_KERNEL);
+
+   if (!pq)
+   goto done;
+
+   pq-counter = 0;
+   pq-sent_counter = 0;
+   INIT_LIST_HEAD(pq-sent);
+
+   mutex_init(pq-lock);
+
+   snprintf(pq-pkt_slab_name, sizeof(pq-pkt_slab_name),
+qib-user-sdma-pkts-%u-%02u.%02u, unit, ctxt, sctxt);
+   pq-pkt_slab = kmem_cache_create(pq-pkt_slab_name,
+sizeof(struct qib_user_sdma_pkt),
+0, 0, NULL);
+
+   if (!pq-pkt_slab)
+   goto err_kfree;
+
+   snprintf(pq-header_cache_name, sizeof(pq-header_cache_name

New source release of libipathverbs-1.2.tar.gz

2009-11-16 Thread Ralph Campbell
I have updated the latest released source tarball for libipathverbs
which can be found at:

http://www.openfabrics.org/downloads/libipathverbs/libipathverbs-1.2.tar.gz

Vlad, please update OFED-1.5 to include this version.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] IB/core: export struct ib_port

2009-11-11 Thread Ralph Campbell
On Wed, 2009-11-11 at 11:19 -0800, Roland Dreier wrote:
  This patch moves the definition of struct ib_port from
   sysfs.c to ib_verbs.h so that HCAs can create files in
   /sys/class/infiniband/hca/ports/N/
 
 um, maybe, but we need to see how it gets used first.  How do you get
 the to struct ib_port in driver code?  Maybe it would make more sense to
 add a way for low-level drivers to pass in port attributes that get
 added when the port structure gets created?

It is used by the new ib_qib driver to expose the SL to VL table
since the user level MPI library (libpsm) constructs packets including
the IB header. After the driver calls ib_register_device(),
it calls device_create_file() to create the files in
/sys/class/infiniband/qib0/. Then it uses struct ib_device-port_list
to get the pointer to ib_port to add a directory similar to gids
and pkeys for each SL.

 By the way, any plans to resume working on the upstream driver for
 qlogic HCAs?  Do you still plan to deprecate ib_ipath and add a new
 driver for new devices?

Yes, this is what I'm working on.
The patch is the only change outside of the hw/qib/ directory.
Do you want to see a preview of the sysfs code?

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] IB/core: export struct ib_port

2009-11-11 Thread Ralph Campbell
On Wed, 2009-11-11 at 15:02 -0800, Roland Dreier wrote:
  | Hmm, maybe we should just add a vls directory with sl0 ... sl15 or
   | something like that in generic code?  I don't see why this needs to be
   | driver-specific code.
   
   No particular reason, it just didn't seem likely to be useful on other
   HCA drivers.   I can redo the patches that way, if people think it's
   the right thing to do.
 
 To me it does seem like something generic.  SLtoVL table is required of
 all CAs, so we might as well create it for all IB devices... as I see it
 the advantages of having it core code are:
 
  - no need to expose internals of sysfs code port structure to low level
drivers (we could also avoid this layering violation by giving a
generic way for low-level drivers to add port attributes)
  - IB-specified info is available for all IB devices with the same
format etc.  It may not be important for non-qlogic devices but there
is some utility in SL mapping for debugging etc.
 
 the only disadvantage I see is that it adds the overhead of having those
 sysfs attributes for all systems with an RDMA devices, even if the
 qlogic driver is never loaded.  But that overhead is pretty much just a
 small amount of extra code that will never be run and a few sysfs
 structures that will never be touched, so it just takes up a little bit
 of memory.  For RDMA-using systems, I can't imagine it matters.
 
  - R.

While this is true for SLtoVL, we create other files which are
device specific under the port directory too.
It seems like we might need to introduce a callback into the driver to
create the port specific sysfs files.

--
To unsubscribe from this list: send the line unsubscribe linux-rdma in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] infiniband-diags/ibportstate: allow changes to CA portinfo parameters

2009-11-05 Thread Ralph Campbell
This patch adds new commands to ibportstate to support initializing
the link for CAs connected back-to-back. It also allows more than
one field to be changed at the same time such as lid 23 arm or
width 1 speed 3 enable.

Signed-off-by: Ralph Campbell ralph.campb...@qlogic.com
---

diff --git a/infiniband-diags/src/ibportstate.c 
b/infiniband-diags/src/ibportstate.c
index e631bfd..192b14e 100644
--- a/infiniband-diags/src/ibportstate.c
+++ b/infiniband-diags/src/ibportstate.c
@@ -46,93 +46,133 @@
 
 #include ibdiag_common.h
 
+enum port_ops {
+   QUERY,
+   ENABLE,
+   RESET,
+   DISABLE,
+   SPEED,
+   WIDTH,
+   DOWN,
+   ARM,
+   ACTIVE,
+   VLS,
+   MTU,
+   LID,
+   SMLID,
+   LMC,
+};
+
 struct ibmad_port *srcport;
+int speed = 15;
+int width = 255;
+int lid;
+int smlid;
+int lmc;
+int mtu;
+int vls;
+
+struct {
+   const char *name;
+   int *val;
+   int set;
+} port_args[] = {
+   { query, NULL, 0 },   /* QUERY */
+   { enable, NULL, 0 },  /* ENABLE */
+   { reset, NULL, 0 },   /* RESET */
+   { disable, NULL, 0 }, /* DISABLE */
+   { speed, speed, 0 }, /* SPEED */
+   { width, width, 0 }, /* WIDTH */
+   { down, NULL, 0 },/* DOWN */
+   { arm, NULL, 0 }, /* ARM */
+   { active, NULL, 0 },  /* ACTIVE */
+   { vls, vls, 0 }, /* VLS */
+   { mtu, mtu, 0 }, /* MTU */
+   { lid, lid, 0 }, /* LID */
+   { smlid, smlid, 0 }, /* SMLID */
+   { lmc, lmc, 0 }, /* LMC */
+};
+
+#define NPORT_ARGS (sizeof(port_args) / sizeof(port_args[0]))
 
 /***/
 
+/*
+ * Return 1 if port is a switch, else zero.
+ */
 static int get_node_info(ib_portid_t * dest, uint8_t * data)
 {
int node_type;
 
if (!smp_query_via(data, dest, IB_ATTR_NODE_INFO, 0, 0, srcport))
-   return -1;
+   IBERROR(smp query nodeinfo failed);
 
node_type = mad_get_field(data, 0, IB_NODE_TYPE_F);
if (node_type == IB_NODE_SWITCH)/* Switch NodeType ? */
-   return 0;
-   else
return 1;
+   else
+   return 0;
 }
 
-static int get_port_info(ib_portid_t * dest, uint8_t * data, int portnum,
-int port_op)
+static void get_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
+{
+   if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
+   IBERROR(smp query portinfo failed);
+}
+
+static void show_port_info(ib_portid_t * dest, uint8_t * data, int portnum)
 {
char buf[2048];
char val[64];
 
-   if (!smp_query_via(data, dest, IB_ATTR_PORT_INFO, portnum, 0, srcport))
-   return -1;
-
-   if (port_op != 4) {
-   mad_dump_portstates(buf, sizeof buf, data, sizeof data);
-   mad_decode_field(data, IB_PORT_LINK_WIDTH_SUPPORTED_F, val);
-   mad_dump_field(IB_PORT_LINK_WIDTH_SUPPORTED_F,
-  buf + strlen(buf), sizeof buf - strlen(buf),
-  val);
-   sprintf(buf + strlen(buf), %s, \n);
-   mad_decode_field(data, IB_PORT_LINK_WIDTH_ENABLED_F, val);
-   mad_dump_field(IB_PORT_LINK_WIDTH_ENABLED_F, buf + strlen(buf),
-  sizeof buf - strlen(buf), val);
-   sprintf(buf + strlen(buf), %s, \n);
-   mad_decode_field(data, IB_PORT_LINK_WIDTH_ACTIVE_F, val);
-   mad_dump_field(IB_PORT_LINK_WIDTH_ACTIVE_F, buf + strlen(buf),
-  sizeof buf - strlen(buf), val);
-   sprintf(buf + strlen(buf), %s, \n);
-   mad_decode_field(data, IB_PORT_LINK_SPEED_SUPPORTED_F, val);
-   mad_dump_field(IB_PORT_LINK_SPEED_SUPPORTED_F,
-  buf + strlen(buf), sizeof buf - strlen(buf),
-  val);
-   sprintf(buf + strlen(buf), %s, \n);
-   mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
-   mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf + strlen(buf),
-  sizeof buf - strlen(buf), val);
-   sprintf(buf + strlen(buf), %s, \n);
-   mad_decode_field(data, IB_PORT_LINK_SPEED_ACTIVE_F, val);
-   mad_dump_field(IB_PORT_LINK_SPEED_ACTIVE_F, buf + strlen(buf),
-  sizeof buf - strlen(buf), val);
-   sprintf(buf + strlen(buf), %s, \n);
-   } else {
-   mad_decode_field(data, IB_PORT_LINK_SPEED_ENABLED_F, val);
-   mad_dump_field(IB_PORT_LINK_SPEED_ENABLED_F, buf, sizeof buf,
-  val);
-   sprintf(buf + strlen(buf), %s, \n);
-   }
+   mad_dump_portstates(buf, sizeof buf, data, sizeof data);
+   mad_decode_field(data, IB_PORT_LID_F, val);
+   mad_dump_field(IB_PORT_LID_F, buf + strlen(buf

<    1   2