aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c22
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.c13
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.h15
4 files changed, 39 insertions, 15 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 01f5aa9cb56d..3d1c1c535038 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -52,7 +52,7 @@
52MODULE_LICENSE("Dual BSD/GPL"); 52MODULE_LICENSE("Dual BSD/GPL");
53MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); 53MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
54MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); 54MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
55MODULE_VERSION("SVNEHCA_0018"); 55MODULE_VERSION("SVNEHCA_0019");
56 56
57int ehca_open_aqp1 = 0; 57int ehca_open_aqp1 = 0;
58int ehca_debug_level = 0; 58int ehca_debug_level = 0;
@@ -790,7 +790,7 @@ int __init ehca_module_init(void)
790 int ret; 790 int ret;
791 791
792 printk(KERN_INFO "eHCA Infiniband Device Driver " 792 printk(KERN_INFO "eHCA Infiniband Device Driver "
793 "(Rel.: SVNEHCA_0018)\n"); 793 "(Rel.: SVNEHCA_0019)\n");
794 idr_init(&ehca_qp_idr); 794 idr_init(&ehca_qp_idr);
795 idr_init(&ehca_cq_idr); 795 idr_init(&ehca_cq_idr);
796 spin_lock_init(&ehca_qp_idr_lock); 796 spin_lock_init(&ehca_qp_idr_lock);
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index cf3e50ee2d06..8682aa50c707 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -732,8 +732,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
732 u64 h_ret; 732 u64 h_ret;
733 struct ipz_queue *squeue; 733 struct ipz_queue *squeue;
734 void *bad_send_wqe_p, *bad_send_wqe_v; 734 void *bad_send_wqe_p, *bad_send_wqe_v;
735 void *squeue_start_p, *squeue_end_p; 735 u64 q_ofs;
736 void *squeue_start_v, *squeue_end_v;
737 struct ehca_wqe *wqe; 736 struct ehca_wqe *wqe;
738 int qp_num = my_qp->ib_qp.qp_num; 737 int qp_num = my_qp->ib_qp.qp_num;
739 738
@@ -755,26 +754,23 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca,
755 if (ehca_debug_level) 754 if (ehca_debug_level)
756 ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num); 755 ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num);
757 squeue = &my_qp->ipz_squeue; 756 squeue = &my_qp->ipz_squeue;
758 squeue_start_p = (void*)virt_to_abs(ipz_qeit_calc(squeue, 0L)); 757 if (ipz_queue_abs_to_offset(squeue, (u64)bad_send_wqe_p, &q_ofs)) {
759 squeue_end_p = squeue_start_p+squeue->queue_length; 758 ehca_err(&shca->ib_device, "failed to get wqe offset qp_num=%x"
760 squeue_start_v = abs_to_virt((u64)squeue_start_p); 759 " bad_send_wqe_p=%p", qp_num, bad_send_wqe_p);
761 squeue_end_v = abs_to_virt((u64)squeue_end_p); 760 return -EFAULT;
762 ehca_dbg(&shca->ib_device, "qp_num=%x squeue_start_v=%p squeue_end_v=%p", 761 }
763 qp_num, squeue_start_v, squeue_end_v);
764 762
765 /* loop sets wqe's purge bit */ 763 /* loop sets wqe's purge bit */
766 wqe = (struct ehca_wqe*)bad_send_wqe_v; 764 wqe = (struct ehca_wqe*)ipz_qeit_calc(squeue, q_ofs);
767 *bad_wqe_cnt = 0; 765 *bad_wqe_cnt = 0;
768 while (wqe->optype != 0xff && wqe->wqef != 0xff) { 766 while (wqe->optype != 0xff && wqe->wqef != 0xff) {
769 if (ehca_debug_level) 767 if (ehca_debug_level)
770 ehca_dmp(wqe, 32, "qp_num=%x wqe", qp_num); 768 ehca_dmp(wqe, 32, "qp_num=%x wqe", qp_num);
771 wqe->nr_of_data_seg = 0; /* suppress data access */ 769 wqe->nr_of_data_seg = 0; /* suppress data access */
772 wqe->wqef = WQEF_PURGE; /* WQE to be purged */ 770 wqe->wqef = WQEF_PURGE; /* WQE to be purged */
773 wqe = (struct ehca_wqe*)((u8*)wqe+squeue->qe_size); 771 q_ofs = ipz_queue_advance_offset(squeue, q_ofs);
772 wqe = (struct ehca_wqe*)ipz_qeit_calc(squeue, q_ofs);
774 *bad_wqe_cnt = (*bad_wqe_cnt)+1; 773 *bad_wqe_cnt = (*bad_wqe_cnt)+1;
775 if ((void*)wqe >= squeue_end_v) {
776 wqe = squeue_start_v;
777 }
778 } 774 }
779 /* 775 /*
780 * bad wqe will be reprocessed and ignored when pol_cq() is called, 776 * bad wqe will be reprocessed and ignored when pol_cq() is called,
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
index e028ff1588cc..bf7a40088f61 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
@@ -70,6 +70,19 @@ void *ipz_qeit_eq_get_inc(struct ipz_queue *queue)
70 return ret; 70 return ret;
71} 71}
72 72
73int ipz_queue_abs_to_offset(struct ipz_queue *queue, u64 addr, u64 *q_offset)
74{
75 int i;
76 for (i = 0; i < queue->queue_length / queue->pagesize; i++) {
77 u64 page = (u64)virt_to_abs(queue->queue_pages[i]);
78 if (addr >= page && addr < page + queue->pagesize) {
79 *q_offset = addr - page + i * queue->pagesize;
80 return 0;
81 }
82 }
83 return -EINVAL;
84}
85
73int ipz_queue_ctor(struct ipz_queue *queue, 86int ipz_queue_ctor(struct ipz_queue *queue,
74 const u32 nr_of_pages, 87 const u32 nr_of_pages,
75 const u32 pagesize, const u32 qe_size, const u32 nr_of_sg) 88 const u32 pagesize, const u32 qe_size, const u32 nr_of_sg)
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
index 2f13509d5257..dc3bda2634b7 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.h
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
@@ -150,6 +150,21 @@ static inline void *ipz_qeit_reset(struct ipz_queue *queue)
150 return ipz_qeit_get(queue); 150 return ipz_qeit_get(queue);
151} 151}
152 152
153/*
154 * return the q_offset corresponding to an absolute address
155 */
156int ipz_queue_abs_to_offset(struct ipz_queue *queue, u64 addr, u64 *q_offset);
157
158/*
159 * return the next queue offset. don't modify the queue.
160 */
161static inline u64 ipz_queue_advance_offset(struct ipz_queue *queue, u64 offset)
162{
163 offset += queue->qe_size;
164 if (offset >= queue->queue_length) offset = 0;
165 return offset;
166}
167
153/* struct generic page table */ 168/* struct generic page table */
154struct ipz_pt { 169struct ipz_pt {
155 u64 entries[EHCA_PT_ENTRIES]; 170 u64 entries[EHCA_PT_ENTRIES];