aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-11-10 16:27:06 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-10 16:27:06 -0500
commit78b9c0f91cf908616b8f9f356e1d1220e727ea88 (patch)
tree84a581820bff0fa9830f18138da02d929e4edcb9 /drivers
parent6b482c6779daaa893b277fc9b70767a7c2e7c5eb (diff)
parent94382f3562e350ed7c8f7dcd6fc968bdece31328 (diff)
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/core/user_mad.c129
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c12
-rw-r--r--drivers/infiniband/core/verbs.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_catas.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c16
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c113
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c22
-rw-r--r--drivers/infiniband/hw/mthca/mthca_wqe.h3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h15
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_fs.c177
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c72
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c26
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c7
18 files changed, 458 insertions, 158 deletions
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index aed5ca23fb22..5ea741f47fc8 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -31,7 +31,7 @@
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE. 32 * SOFTWARE.
33 * 33 *
34 * $Id: user_mad.c 2814 2005-07-06 19:14:09Z halr $ 34 * $Id: user_mad.c 4010 2005-11-09 23:11:56Z roland $
35 */ 35 */
36 36
37#include <linux/module.h> 37#include <linux/module.h>
@@ -110,13 +110,13 @@ struct ib_umad_device {
110}; 110};
111 111
112struct ib_umad_file { 112struct ib_umad_file {
113 struct ib_umad_port *port; 113 struct ib_umad_port *port;
114 struct list_head recv_list; 114 struct list_head recv_list;
115 struct list_head port_list; 115 struct list_head port_list;
116 spinlock_t recv_lock; 116 spinlock_t recv_lock;
117 wait_queue_head_t recv_wait; 117 wait_queue_head_t recv_wait;
118 struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; 118 struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS];
119 struct ib_mr *mr[IB_UMAD_MAX_AGENTS]; 119 int agents_dead;
120}; 120};
121 121
122struct ib_umad_packet { 122struct ib_umad_packet {
@@ -145,6 +145,12 @@ static void ib_umad_release_dev(struct kref *ref)
145 kfree(dev); 145 kfree(dev);
146} 146}
147 147
148/* caller must hold port->mutex at least for reading */
149static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id)
150{
151 return file->agents_dead ? NULL : file->agent[id];
152}
153
148static int queue_packet(struct ib_umad_file *file, 154static int queue_packet(struct ib_umad_file *file,
149 struct ib_mad_agent *agent, 155 struct ib_mad_agent *agent,
150 struct ib_umad_packet *packet) 156 struct ib_umad_packet *packet)
@@ -152,10 +158,11 @@ static int queue_packet(struct ib_umad_file *file,
152 int ret = 1; 158 int ret = 1;
153 159
154 down_read(&file->port->mutex); 160 down_read(&file->port->mutex);
161
155 for (packet->mad.hdr.id = 0; 162 for (packet->mad.hdr.id = 0;
156 packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; 163 packet->mad.hdr.id < IB_UMAD_MAX_AGENTS;
157 packet->mad.hdr.id++) 164 packet->mad.hdr.id++)
158 if (agent == file->agent[packet->mad.hdr.id]) { 165 if (agent == __get_agent(file, packet->mad.hdr.id)) {
159 spin_lock_irq(&file->recv_lock); 166 spin_lock_irq(&file->recv_lock);
160 list_add_tail(&packet->list, &file->recv_list); 167 list_add_tail(&packet->list, &file->recv_list);
161 spin_unlock_irq(&file->recv_lock); 168 spin_unlock_irq(&file->recv_lock);
@@ -327,7 +334,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
327 334
328 down_read(&file->port->mutex); 335 down_read(&file->port->mutex);
329 336
330 agent = file->agent[packet->mad.hdr.id]; 337 agent = __get_agent(file, packet->mad.hdr.id);
331 if (!agent) { 338 if (!agent) {
332 ret = -EINVAL; 339 ret = -EINVAL;
333 goto err_up; 340 goto err_up;
@@ -481,7 +488,7 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg)
481 } 488 }
482 489
483 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id) 490 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id)
484 if (!file->agent[agent_id]) 491 if (!__get_agent(file, agent_id))
485 goto found; 492 goto found;
486 493
487 ret = -ENOMEM; 494 ret = -ENOMEM;
@@ -505,29 +512,15 @@ found:
505 goto out; 512 goto out;
506 } 513 }
507 514
508 file->agent[agent_id] = agent;
509
510 file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE);
511 if (IS_ERR(file->mr[agent_id])) {
512 ret = -ENOMEM;
513 goto err;
514 }
515
516 if (put_user(agent_id, 515 if (put_user(agent_id,
517 (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) { 516 (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) {
518 ret = -EFAULT; 517 ret = -EFAULT;
519 goto err_mr; 518 ib_unregister_mad_agent(agent);
519 goto out;
520 } 520 }
521 521
522 file->agent[agent_id] = agent;
522 ret = 0; 523 ret = 0;
523 goto out;
524
525err_mr:
526 ib_dereg_mr(file->mr[agent_id]);
527
528err:
529 file->agent[agent_id] = NULL;
530 ib_unregister_mad_agent(agent);
531 524
532out: 525out:
533 up_write(&file->port->mutex); 526 up_write(&file->port->mutex);
@@ -536,27 +529,29 @@ out:
536 529
537static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) 530static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg)
538{ 531{
532 struct ib_mad_agent *agent = NULL;
539 u32 id; 533 u32 id;
540 int ret = 0; 534 int ret = 0;
541 535
542 down_write(&file->port->mutex); 536 if (get_user(id, (u32 __user *) arg))
537 return -EFAULT;
543 538
544 if (get_user(id, (u32 __user *) arg)) { 539 down_write(&file->port->mutex);
545 ret = -EFAULT;
546 goto out;
547 }
548 540
549 if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) { 541 if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !__get_agent(file, id)) {
550 ret = -EINVAL; 542 ret = -EINVAL;
551 goto out; 543 goto out;
552 } 544 }
553 545
554 ib_dereg_mr(file->mr[id]); 546 agent = file->agent[id];
555 ib_unregister_mad_agent(file->agent[id]);
556 file->agent[id] = NULL; 547 file->agent[id] = NULL;
557 548
558out: 549out:
559 up_write(&file->port->mutex); 550 up_write(&file->port->mutex);
551
552 if (agent)
553 ib_unregister_mad_agent(agent);
554
560 return ret; 555 return ret;
561} 556}
562 557
@@ -621,23 +616,29 @@ static int ib_umad_close(struct inode *inode, struct file *filp)
621 struct ib_umad_file *file = filp->private_data; 616 struct ib_umad_file *file = filp->private_data;
622 struct ib_umad_device *dev = file->port->umad_dev; 617 struct ib_umad_device *dev = file->port->umad_dev;
623 struct ib_umad_packet *packet, *tmp; 618 struct ib_umad_packet *packet, *tmp;
619 int already_dead;
624 int i; 620 int i;
625 621
626 down_write(&file->port->mutex); 622 down_write(&file->port->mutex);
627 for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) 623
628 if (file->agent[i]) { 624 already_dead = file->agents_dead;
629 ib_dereg_mr(file->mr[i]); 625 file->agents_dead = 1;
630 ib_unregister_mad_agent(file->agent[i]);
631 }
632 626
633 list_for_each_entry_safe(packet, tmp, &file->recv_list, list) 627 list_for_each_entry_safe(packet, tmp, &file->recv_list, list)
634 kfree(packet); 628 kfree(packet);
635 629
636 list_del(&file->port_list); 630 list_del(&file->port_list);
637 up_write(&file->port->mutex);
638 631
639 kfree(file); 632 downgrade_write(&file->port->mutex);
633
634 if (!already_dead)
635 for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
636 if (file->agent[i])
637 ib_unregister_mad_agent(file->agent[i]);
638
639 up_read(&file->port->mutex);
640 640
641 kfree(file);
641 kref_put(&dev->ref, ib_umad_release_dev); 642 kref_put(&dev->ref, ib_umad_release_dev);
642 643
643 return 0; 644 return 0;
@@ -801,7 +802,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
801 goto err_class; 802 goto err_class;
802 port->sm_dev->owner = THIS_MODULE; 803 port->sm_dev->owner = THIS_MODULE;
803 port->sm_dev->ops = &umad_sm_fops; 804 port->sm_dev->ops = &umad_sm_fops;
804 kobject_set_name(&port->dev->kobj, "issm%d", port->dev_num); 805 kobject_set_name(&port->sm_dev->kobj, "issm%d", port->dev_num);
805 if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) 806 if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
806 goto err_sm_cdev; 807 goto err_sm_cdev;
807 808
@@ -863,14 +864,36 @@ static void ib_umad_kill_port(struct ib_umad_port *port)
863 864
864 port->ib_dev = NULL; 865 port->ib_dev = NULL;
865 866
866 list_for_each_entry(file, &port->file_list, port_list) 867 /*
867 for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) { 868 * Now go through the list of files attached to this port and
868 if (!file->agent[id]) 869 * unregister all of their MAD agents. We need to hold
869 continue; 870 * port->mutex while doing this to avoid racing with
870 ib_dereg_mr(file->mr[id]); 871 * ib_umad_close(), but we can't hold the mutex for writing
871 ib_unregister_mad_agent(file->agent[id]); 872 * while calling ib_unregister_mad_agent(), since that might
872 file->agent[id] = NULL; 873 * deadlock by calling back into queue_packet(). So we
873 } 874 * downgrade our lock to a read lock, and then drop and
875 * reacquire the write lock for the next iteration.
876 *
877 * We do list_del_init() on the file's list_head so that the
878 * list_del in ib_umad_close() is still OK, even after the
879 * file is removed from the list.
880 */
881 while (!list_empty(&port->file_list)) {
882 file = list_entry(port->file_list.next, struct ib_umad_file,
883 port_list);
884
885 file->agents_dead = 1;
886 list_del_init(&file->port_list);
887
888 downgrade_write(&port->mutex);
889
890 for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id)
891 if (file->agent[id])
892 ib_unregister_mad_agent(file->agent[id]);
893
894 up_read(&port->mutex);
895 down_write(&port->mutex);
896 }
874 897
875 up_write(&port->mutex); 898 up_write(&port->mutex);
876 899
@@ -913,7 +936,7 @@ static void ib_umad_add_one(struct ib_device *device)
913 936
914err: 937err:
915 while (--i >= s) 938 while (--i >= s)
916 ib_umad_kill_port(&umad_dev->port[i]); 939 ib_umad_kill_port(&umad_dev->port[i - s]);
917 940
918 kref_put(&umad_dev->ref, ib_umad_release_dev); 941 kref_put(&umad_dev->ref, ib_umad_release_dev);
919} 942}
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 63a74151c60b..ed45da892b1c 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -708,7 +708,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
708 resp->wc[i].opcode = wc[i].opcode; 708 resp->wc[i].opcode = wc[i].opcode;
709 resp->wc[i].vendor_err = wc[i].vendor_err; 709 resp->wc[i].vendor_err = wc[i].vendor_err;
710 resp->wc[i].byte_len = wc[i].byte_len; 710 resp->wc[i].byte_len = wc[i].byte_len;
711 resp->wc[i].imm_data = wc[i].imm_data; 711 resp->wc[i].imm_data = (__u32 __force) wc[i].imm_data;
712 resp->wc[i].qp_num = wc[i].qp_num; 712 resp->wc[i].qp_num = wc[i].qp_num;
713 resp->wc[i].src_qp = wc[i].src_qp; 713 resp->wc[i].src_qp = wc[i].src_qp;
714 resp->wc[i].wc_flags = wc[i].wc_flags; 714 resp->wc[i].wc_flags = wc[i].wc_flags;
@@ -908,7 +908,12 @@ retry:
908 if (ret) 908 if (ret)
909 goto err_destroy; 909 goto err_destroy;
910 910
911 resp.qp_handle = uobj->uobject.id; 911 resp.qp_handle = uobj->uobject.id;
912 resp.max_recv_sge = attr.cap.max_recv_sge;
913 resp.max_send_sge = attr.cap.max_send_sge;
914 resp.max_recv_wr = attr.cap.max_recv_wr;
915 resp.max_send_wr = attr.cap.max_send_wr;
916 resp.max_inline_data = attr.cap.max_inline_data;
912 917
913 if (copy_to_user((void __user *) (unsigned long) cmd.response, 918 if (copy_to_user((void __user *) (unsigned long) cmd.response,
914 &resp, sizeof resp)) { 919 &resp, sizeof resp)) {
@@ -1135,7 +1140,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1135 next->num_sge = user_wr->num_sge; 1140 next->num_sge = user_wr->num_sge;
1136 next->opcode = user_wr->opcode; 1141 next->opcode = user_wr->opcode;
1137 next->send_flags = user_wr->send_flags; 1142 next->send_flags = user_wr->send_flags;
1138 next->imm_data = user_wr->imm_data; 1143 next->imm_data = (__be32 __force) user_wr->imm_data;
1139 1144
1140 if (qp->qp_type == IB_QPT_UD) { 1145 if (qp->qp_type == IB_QPT_UD) {
1141 next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr, 1146 next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr,
@@ -1701,7 +1706,6 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
1701 } 1706 }
1702 1707
1703 attr.max_wr = cmd.max_wr; 1708 attr.max_wr = cmd.max_wr;
1704 attr.max_sge = cmd.max_sge;
1705 attr.srq_limit = cmd.srq_limit; 1709 attr.srq_limit = cmd.srq_limit;
1706 1710
1707 ret = ib_modify_srq(srq, &attr, cmd.attr_mask); 1711 ret = ib_modify_srq(srq, &attr, cmd.attr_mask);
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 4186cc888ea5..4c15e112736c 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -325,16 +325,8 @@ EXPORT_SYMBOL(ib_destroy_cq);
325int ib_resize_cq(struct ib_cq *cq, 325int ib_resize_cq(struct ib_cq *cq,
326 int cqe) 326 int cqe)
327{ 327{
328 int ret; 328 return cq->device->resize_cq ?
329 329 cq->device->resize_cq(cq, cqe) : -ENOSYS;
330 if (!cq->device->resize_cq)
331 return -ENOSYS;
332
333 ret = cq->device->resize_cq(cq, &cqe);
334 if (!ret)
335 cq->cqe = cqe;
336
337 return ret;
338} 330}
339EXPORT_SYMBOL(ib_resize_cq); 331EXPORT_SYMBOL(ib_resize_cq);
340 332
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
index 25ebab64bc42..c3bec7490f52 100644
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -97,7 +97,7 @@ static void poll_catas(unsigned long dev_ptr)
97 } 97 }
98 98
99 spin_lock_irqsave(&catas_lock, flags); 99 spin_lock_irqsave(&catas_lock, flags);
100 if (dev->catas_err.stop) 100 if (!dev->catas_err.stop)
101 mod_timer(&dev->catas_err.timer, 101 mod_timer(&dev->catas_err.timer,
102 jiffies + MTHCA_CATAS_POLL_INTERVAL); 102 jiffies + MTHCA_CATAS_POLL_INTERVAL);
103 spin_unlock_irqrestore(&catas_lock, flags); 103 spin_unlock_irqrestore(&catas_lock, flags);
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 49f211d55df7..9ed34587fc5c 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1060,6 +1060,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1060 dev_lim->hca.arbel.resize_srq = field & 1; 1060 dev_lim->hca.arbel.resize_srq = field & 1;
1061 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); 1061 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET);
1062 dev_lim->max_sg = min_t(int, field, dev_lim->max_sg); 1062 dev_lim->max_sg = min_t(int, field, dev_lim->max_sg);
1063 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MAX_DESC_SZ_RQ_OFFSET);
1064 dev_lim->max_desc_sz = min_t(int, size, dev_lim->max_desc_sz);
1063 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET); 1065 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET);
1064 dev_lim->mpt_entry_sz = size; 1066 dev_lim->mpt_entry_sz = size;
1065 MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET); 1067 MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET);
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index f98e23555826..4a8adcef2079 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -258,7 +258,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
258{ 258{
259 struct mthca_cq *cq; 259 struct mthca_cq *cq;
260 struct mthca_cqe *cqe; 260 struct mthca_cqe *cqe;
261 int prod_index; 261 u32 prod_index;
262 int nfreed = 0; 262 int nfreed = 0;
263 263
264 spin_lock_irq(&dev->cq_table.lock); 264 spin_lock_irq(&dev->cq_table.lock);
@@ -293,19 +293,15 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
293 * Now sweep backwards through the CQ, removing CQ entries 293 * Now sweep backwards through the CQ, removing CQ entries
294 * that match our QP by copying older entries on top of them. 294 * that match our QP by copying older entries on top of them.
295 */ 295 */
296 while (prod_index > cq->cons_index) { 296 while ((int) --prod_index - (int) cq->cons_index >= 0) {
297 cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe); 297 cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
298 if (cqe->my_qpn == cpu_to_be32(qpn)) { 298 if (cqe->my_qpn == cpu_to_be32(qpn)) {
299 if (srq) 299 if (srq)
300 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); 300 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe));
301 ++nfreed; 301 ++nfreed;
302 } 302 } else if (nfreed)
303 else if (nfreed) 303 memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe),
304 memcpy(get_cqe(cq, (prod_index - 1 + nfreed) & 304 cqe, MTHCA_CQ_ENTRY_SIZE);
305 cq->ibcq.cqe),
306 cqe,
307 MTHCA_CQ_ENTRY_SIZE);
308 --prod_index;
309 } 305 }
310 306
311 if (nfreed) { 307 if (nfreed) {
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index e7e5d3b4f004..497ff794ef6a 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -131,6 +131,7 @@ struct mthca_limits {
131 int max_sg; 131 int max_sg;
132 int num_qps; 132 int num_qps;
133 int max_wqes; 133 int max_wqes;
134 int max_desc_sz;
134 int max_qp_init_rdma; 135 int max_qp_init_rdma;
135 int reserved_qps; 136 int reserved_qps;
136 int num_srqs; 137 int num_srqs;
@@ -154,6 +155,7 @@ struct mthca_limits {
154 int reserved_mcgs; 155 int reserved_mcgs;
155 int num_pds; 156 int num_pds;
156 int reserved_pds; 157 int reserved_pds;
158 u32 page_size_cap;
157 u32 flags; 159 u32 flags;
158 u8 port_width_cap; 160 u8 port_width_cap;
159}; 161};
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 45c6328e780c..147f248a8073 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -168,6 +168,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
168 mdev->limits.max_srq_wqes = dev_lim->max_srq_sz; 168 mdev->limits.max_srq_wqes = dev_lim->max_srq_sz;
169 mdev->limits.reserved_srqs = dev_lim->reserved_srqs; 169 mdev->limits.reserved_srqs = dev_lim->reserved_srqs;
170 mdev->limits.reserved_eecs = dev_lim->reserved_eecs; 170 mdev->limits.reserved_eecs = dev_lim->reserved_eecs;
171 mdev->limits.max_desc_sz = dev_lim->max_desc_sz;
171 /* 172 /*
172 * Subtract 1 from the limit because we need to allocate a 173 * Subtract 1 from the limit because we need to allocate a
173 * spare CQE so the HCA HW can tell the difference between an 174 * spare CQE so the HCA HW can tell the difference between an
@@ -181,6 +182,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
181 mdev->limits.reserved_uars = dev_lim->reserved_uars; 182 mdev->limits.reserved_uars = dev_lim->reserved_uars;
182 mdev->limits.reserved_pds = dev_lim->reserved_pds; 183 mdev->limits.reserved_pds = dev_lim->reserved_pds;
183 mdev->limits.port_width_cap = dev_lim->max_port_width; 184 mdev->limits.port_width_cap = dev_lim->max_port_width;
185 mdev->limits.page_size_cap = ~(u32) (dev_lim->min_page_sz - 1);
184 mdev->limits.flags = dev_lim->flags; 186 mdev->limits.flags = dev_lim->flags;
185 187
186 /* IB_DEVICE_RESIZE_MAX_WR not supported by driver. 188 /* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 6b0166668269..4cc7e2846df1 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -90,6 +90,7 @@ static int mthca_query_device(struct ib_device *ibdev,
90 memcpy(&props->node_guid, out_mad->data + 12, 8); 90 memcpy(&props->node_guid, out_mad->data + 12, 8);
91 91
92 props->max_mr_size = ~0ull; 92 props->max_mr_size = ~0ull;
93 props->page_size_cap = mdev->limits.page_size_cap;
93 props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps; 94 props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps;
94 props->max_qp_wr = mdev->limits.max_wqes; 95 props->max_qp_wr = mdev->limits.max_wqes;
95 props->max_sge = mdev->limits.max_sg; 96 props->max_sge = mdev->limits.max_sg;
@@ -615,11 +616,11 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
615 return ERR_PTR(err); 616 return ERR_PTR(err);
616 } 617 }
617 618
618 init_attr->cap.max_inline_data = 0;
619 init_attr->cap.max_send_wr = qp->sq.max; 619 init_attr->cap.max_send_wr = qp->sq.max;
620 init_attr->cap.max_recv_wr = qp->rq.max; 620 init_attr->cap.max_recv_wr = qp->rq.max;
621 init_attr->cap.max_send_sge = qp->sq.max_gs; 621 init_attr->cap.max_send_sge = qp->sq.max_gs;
622 init_attr->cap.max_recv_sge = qp->rq.max_gs; 622 init_attr->cap.max_recv_sge = qp->rq.max_gs;
623 init_attr->cap.max_inline_data = qp->max_inline_data;
623 624
624 return &qp->ibqp; 625 return &qp->ibqp;
625} 626}
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
index bcd4b01a339c..1e73947b4702 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -251,6 +251,7 @@ struct mthca_qp {
251 struct mthca_wq sq; 251 struct mthca_wq sq;
252 enum ib_sig_type sq_policy; 252 enum ib_sig_type sq_policy;
253 int send_wqe_offset; 253 int send_wqe_offset;
254 int max_inline_data;
254 255
255 u64 *wrid; 256 u64 *wrid;
256 union mthca_buf queue; 257 union mthca_buf queue;
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 8852ea477c21..760c418d5bc9 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -885,6 +885,48 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
885 return err; 885 return err;
886} 886}
887 887
888static void mthca_adjust_qp_caps(struct mthca_dev *dev,
889 struct mthca_pd *pd,
890 struct mthca_qp *qp)
891{
892 int max_data_size;
893
894 /*
895 * Calculate the maximum size of WQE s/g segments, excluding
896 * the next segment and other non-data segments.
897 */
898 max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) -
899 sizeof (struct mthca_next_seg);
900
901 switch (qp->transport) {
902 case MLX:
903 max_data_size -= 2 * sizeof (struct mthca_data_seg);
904 break;
905
906 case UD:
907 if (mthca_is_memfree(dev))
908 max_data_size -= sizeof (struct mthca_arbel_ud_seg);
909 else
910 max_data_size -= sizeof (struct mthca_tavor_ud_seg);
911 break;
912
913 default:
914 max_data_size -= sizeof (struct mthca_raddr_seg);
915 break;
916 }
917
918 /* We don't support inline data for kernel QPs (yet). */
919 if (!pd->ibpd.uobject)
920 qp->max_inline_data = 0;
921 else
922 qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
923
924 qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg);
925 qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
926 sizeof (struct mthca_next_seg)) /
927 sizeof (struct mthca_data_seg);
928}
929
888/* 930/*
889 * Allocate and register buffer for WQEs. qp->rq.max, sq.max, 931 * Allocate and register buffer for WQEs. qp->rq.max, sq.max,
890 * rq.max_gs and sq.max_gs must all be assigned. 932 * rq.max_gs and sq.max_gs must all be assigned.
@@ -902,27 +944,53 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
902 size = sizeof (struct mthca_next_seg) + 944 size = sizeof (struct mthca_next_seg) +
903 qp->rq.max_gs * sizeof (struct mthca_data_seg); 945 qp->rq.max_gs * sizeof (struct mthca_data_seg);
904 946
947 if (size > dev->limits.max_desc_sz)
948 return -EINVAL;
949
905 for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size; 950 for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size;
906 qp->rq.wqe_shift++) 951 qp->rq.wqe_shift++)
907 ; /* nothing */ 952 ; /* nothing */
908 953
909 size = sizeof (struct mthca_next_seg) + 954 size = qp->sq.max_gs * sizeof (struct mthca_data_seg);
910 qp->sq.max_gs * sizeof (struct mthca_data_seg);
911 switch (qp->transport) { 955 switch (qp->transport) {
912 case MLX: 956 case MLX:
913 size += 2 * sizeof (struct mthca_data_seg); 957 size += 2 * sizeof (struct mthca_data_seg);
914 break; 958 break;
959
915 case UD: 960 case UD:
916 if (mthca_is_memfree(dev)) 961 size += mthca_is_memfree(dev) ?
917 size += sizeof (struct mthca_arbel_ud_seg); 962 sizeof (struct mthca_arbel_ud_seg) :
918 else 963 sizeof (struct mthca_tavor_ud_seg);
919 size += sizeof (struct mthca_tavor_ud_seg);
920 break; 964 break;
965
966 case UC:
967 size += sizeof (struct mthca_raddr_seg);
968 break;
969
970 case RC:
971 size += sizeof (struct mthca_raddr_seg);
972 /*
973 * An atomic op will require an atomic segment, a
974 * remote address segment and one scatter entry.
975 */
976 size = max_t(int, size,
977 sizeof (struct mthca_atomic_seg) +
978 sizeof (struct mthca_raddr_seg) +
979 sizeof (struct mthca_data_seg));
980 break;
981
921 default: 982 default:
922 /* bind seg is as big as atomic + raddr segs */ 983 break;
923 size += sizeof (struct mthca_bind_seg);
924 } 984 }
925 985
986 /* Make sure that we have enough space for a bind request */
987 size = max_t(int, size, sizeof (struct mthca_bind_seg));
988
989 size += sizeof (struct mthca_next_seg);
990
991 if (size > dev->limits.max_desc_sz)
992 return -EINVAL;
993
926 for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size; 994 for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size;
927 qp->sq.wqe_shift++) 995 qp->sq.wqe_shift++)
928 ; /* nothing */ 996 ; /* nothing */
@@ -1066,6 +1134,8 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1066 return ret; 1134 return ret;
1067 } 1135 }
1068 1136
1137 mthca_adjust_qp_caps(dev, pd, qp);
1138
1069 /* 1139 /*
1070 * If this is a userspace QP, we're done now. The doorbells 1140 * If this is a userspace QP, we're done now. The doorbells
1071 * will be allocated and buffers will be initialized in 1141 * will be allocated and buffers will be initialized in
@@ -1486,8 +1556,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1486 } 1556 }
1487 1557
1488 wqe += sizeof (struct mthca_atomic_seg); 1558 wqe += sizeof (struct mthca_atomic_seg);
1489 size += sizeof (struct mthca_raddr_seg) / 16 + 1559 size += (sizeof (struct mthca_raddr_seg) +
1490 sizeof (struct mthca_atomic_seg); 1560 sizeof (struct mthca_atomic_seg)) / 16;
1491 break; 1561 break;
1492 1562
1493 case IB_WR_RDMA_WRITE: 1563 case IB_WR_RDMA_WRITE:
@@ -1637,6 +1707,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1637{ 1707{
1638 struct mthca_dev *dev = to_mdev(ibqp->device); 1708 struct mthca_dev *dev = to_mdev(ibqp->device);
1639 struct mthca_qp *qp = to_mqp(ibqp); 1709 struct mthca_qp *qp = to_mqp(ibqp);
1710 __be32 doorbell[2];
1640 unsigned long flags; 1711 unsigned long flags;
1641 int err = 0; 1712 int err = 0;
1642 int nreq; 1713 int nreq;
@@ -1654,6 +1725,22 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1654 ind = qp->rq.next_ind; 1725 ind = qp->rq.next_ind;
1655 1726
1656 for (nreq = 0; wr; ++nreq, wr = wr->next) { 1727 for (nreq = 0; wr; ++nreq, wr = wr->next) {
1728 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
1729 nreq = 0;
1730
1731 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1732 doorbell[1] = cpu_to_be32(qp->qpn << 8);
1733
1734 wmb();
1735
1736 mthca_write64(doorbell,
1737 dev->kar + MTHCA_RECEIVE_DOORBELL,
1738 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
1739
1740 qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB;
1741 size0 = 0;
1742 }
1743
1657 if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { 1744 if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) {
1658 mthca_err(dev, "RQ %06x full (%u head, %u tail," 1745 mthca_err(dev, "RQ %06x full (%u head, %u tail,"
1659 " %d max, %d nreq)\n", qp->qpn, 1746 " %d max, %d nreq)\n", qp->qpn,
@@ -1711,8 +1798,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1711 1798
1712out: 1799out:
1713 if (likely(nreq)) { 1800 if (likely(nreq)) {
1714 __be32 doorbell[2];
1715
1716 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); 1801 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1717 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq); 1802 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
1718 1803
@@ -1806,8 +1891,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1806 } 1891 }
1807 1892
1808 wqe += sizeof (struct mthca_atomic_seg); 1893 wqe += sizeof (struct mthca_atomic_seg);
1809 size += sizeof (struct mthca_raddr_seg) / 16 + 1894 size += (sizeof (struct mthca_raddr_seg) +
1810 sizeof (struct mthca_atomic_seg); 1895 sizeof (struct mthca_atomic_seg)) / 16;
1811 break; 1896 break;
1812 1897
1813 case IB_WR_RDMA_READ: 1898 case IB_WR_RDMA_READ:
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 26d5161fde07..f7d234295efe 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -417,6 +417,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
417{ 417{
418 struct mthca_dev *dev = to_mdev(ibsrq->device); 418 struct mthca_dev *dev = to_mdev(ibsrq->device);
419 struct mthca_srq *srq = to_msrq(ibsrq); 419 struct mthca_srq *srq = to_msrq(ibsrq);
420 __be32 doorbell[2];
420 unsigned long flags; 421 unsigned long flags;
421 int err = 0; 422 int err = 0;
422 int first_ind; 423 int first_ind;
@@ -432,6 +433,25 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
432 first_ind = srq->first_free; 433 first_ind = srq->first_free;
433 434
434 for (nreq = 0; wr; ++nreq, wr = wr->next) { 435 for (nreq = 0; wr; ++nreq, wr = wr->next) {
436 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
437 nreq = 0;
438
439 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
440 doorbell[1] = cpu_to_be32(srq->srqn << 8);
441
442 /*
443 * Make sure that descriptors are written
444 * before doorbell is rung.
445 */
446 wmb();
447
448 mthca_write64(doorbell,
449 dev->kar + MTHCA_RECEIVE_DOORBELL,
450 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
451
452 first_ind = srq->first_free;
453 }
454
435 ind = srq->first_free; 455 ind = srq->first_free;
436 456
437 if (ind < 0) { 457 if (ind < 0) {
@@ -494,8 +514,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
494 } 514 }
495 515
496 if (likely(nreq)) { 516 if (likely(nreq)) {
497 __be32 doorbell[2];
498
499 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift); 517 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
500 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq); 518 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq);
501 519
diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h
index 1f4c0ff28f79..73f1c0b9021e 100644
--- a/drivers/infiniband/hw/mthca/mthca_wqe.h
+++ b/drivers/infiniband/hw/mthca/mthca_wqe.h
@@ -49,7 +49,8 @@ enum {
49}; 49};
50 50
51enum { 51enum {
52 MTHCA_INVAL_LKEY = 0x100 52 MTHCA_INVAL_LKEY = 0x100,
53 MTHCA_TAVOR_MAX_WQES_PER_RECV_DB = 256
53}; 54};
54 55
55struct mthca_next_seg { 56struct mthca_next_seg {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 0095acc0fbbe..9923a15a9996 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -179,6 +179,7 @@ struct ipoib_dev_priv {
179#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 179#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
180 struct list_head fs_list; 180 struct list_head fs_list;
181 struct dentry *mcg_dentry; 181 struct dentry *mcg_dentry;
182 struct dentry *path_dentry;
182#endif 183#endif
183}; 184};
184 185
@@ -270,7 +271,6 @@ void ipoib_mcast_dev_flush(struct net_device *dev);
270 271
271#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 272#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
272struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev); 273struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
273void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter);
274int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter); 274int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
275void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter, 275void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
276 union ib_gid *gid, 276 union ib_gid *gid,
@@ -278,6 +278,11 @@ void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
278 unsigned int *queuelen, 278 unsigned int *queuelen,
279 unsigned int *complete, 279 unsigned int *complete,
280 unsigned int *send_only); 280 unsigned int *send_only);
281
282struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev);
283int ipoib_path_iter_next(struct ipoib_path_iter *iter);
284void ipoib_path_iter_read(struct ipoib_path_iter *iter,
285 struct ipoib_path *path);
281#endif 286#endif
282 287
283int ipoib_mcast_attach(struct net_device *dev, u16 mlid, 288int ipoib_mcast_attach(struct net_device *dev, u16 mlid,
@@ -299,13 +304,13 @@ void ipoib_pkey_poll(void *dev);
299int ipoib_pkey_dev_delay_open(struct net_device *dev); 304int ipoib_pkey_dev_delay_open(struct net_device *dev);
300 305
301#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 306#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
302int ipoib_create_debug_file(struct net_device *dev); 307void ipoib_create_debug_files(struct net_device *dev);
303void ipoib_delete_debug_file(struct net_device *dev); 308void ipoib_delete_debug_files(struct net_device *dev);
304int ipoib_register_debugfs(void); 309int ipoib_register_debugfs(void);
305void ipoib_unregister_debugfs(void); 310void ipoib_unregister_debugfs(void);
306#else 311#else
307static inline int ipoib_create_debug_file(struct net_device *dev) { return 0; } 312static inline void ipoib_create_debug_files(struct net_device *dev) { }
308static inline void ipoib_delete_debug_file(struct net_device *dev) { } 313static inline void ipoib_delete_debug_files(struct net_device *dev) { }
309static inline int ipoib_register_debugfs(void) { return 0; } 314static inline int ipoib_register_debugfs(void) { return 0; }
310static inline void ipoib_unregister_debugfs(void) { } 315static inline void ipoib_unregister_debugfs(void) { }
311#endif 316#endif
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index 38b150f775e7..685258e34034 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -43,6 +43,18 @@ struct file_operations;
43 43
44static struct dentry *ipoib_root; 44static struct dentry *ipoib_root;
45 45
46static void format_gid(union ib_gid *gid, char *buf)
47{
48 int i, n;
49
50 for (n = 0, i = 0; i < 8; ++i) {
51 n += sprintf(buf + n, "%x",
52 be16_to_cpu(((__be16 *) gid->raw)[i]));
53 if (i < 7)
54 buf[n++] = ':';
55 }
56}
57
46static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos) 58static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
47{ 59{
48 struct ipoib_mcast_iter *iter; 60 struct ipoib_mcast_iter *iter;
@@ -54,7 +66,7 @@ static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
54 66
55 while (n--) { 67 while (n--) {
56 if (ipoib_mcast_iter_next(iter)) { 68 if (ipoib_mcast_iter_next(iter)) {
57 ipoib_mcast_iter_free(iter); 69 kfree(iter);
58 return NULL; 70 return NULL;
59 } 71 }
60 } 72 }
@@ -70,7 +82,7 @@ static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,
70 (*pos)++; 82 (*pos)++;
71 83
72 if (ipoib_mcast_iter_next(iter)) { 84 if (ipoib_mcast_iter_next(iter)) {
73 ipoib_mcast_iter_free(iter); 85 kfree(iter);
74 return NULL; 86 return NULL;
75 } 87 }
76 88
@@ -87,32 +99,32 @@ static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)
87 struct ipoib_mcast_iter *iter = iter_ptr; 99 struct ipoib_mcast_iter *iter = iter_ptr;
88 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; 100 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
89 union ib_gid mgid; 101 union ib_gid mgid;
90 int i, n;
91 unsigned long created; 102 unsigned long created;
92 unsigned int queuelen, complete, send_only; 103 unsigned int queuelen, complete, send_only;
93 104
94 if (iter) { 105 if (!iter)
95 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen, 106 return 0;
96 &complete, &send_only);
97 107
98 for (n = 0, i = 0; i < sizeof mgid / 2; ++i) { 108 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
99 n += sprintf(gid_buf + n, "%x", 109 &complete, &send_only);
100 be16_to_cpu(((__be16 *) mgid.raw)[i]));
101 if (i < sizeof mgid / 2 - 1)
102 gid_buf[n++] = ':';
103 }
104 }
105 110
106 seq_printf(file, "GID: %*s", -(1 + (int) sizeof gid_buf), gid_buf); 111 format_gid(&mgid, gid_buf);
107 112
108 seq_printf(file, 113 seq_printf(file,
109 " created: %10ld queuelen: %4d complete: %d send_only: %d\n", 114 "GID: %s\n"
110 created, queuelen, complete, send_only); 115 " created: %10ld\n"
116 " queuelen: %9d\n"
117 " complete: %9s\n"
118 " send_only: %8s\n"
119 "\n",
120 gid_buf, created, queuelen,
121 complete ? "yes" : "no",
122 send_only ? "yes" : "no");
111 123
112 return 0; 124 return 0;
113} 125}
114 126
115static struct seq_operations ipoib_seq_ops = { 127static struct seq_operations ipoib_mcg_seq_ops = {
116 .start = ipoib_mcg_seq_start, 128 .start = ipoib_mcg_seq_start,
117 .next = ipoib_mcg_seq_next, 129 .next = ipoib_mcg_seq_next,
118 .stop = ipoib_mcg_seq_stop, 130 .stop = ipoib_mcg_seq_stop,
@@ -124,7 +136,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
124 struct seq_file *seq; 136 struct seq_file *seq;
125 int ret; 137 int ret;
126 138
127 ret = seq_open(file, &ipoib_seq_ops); 139 ret = seq_open(file, &ipoib_mcg_seq_ops);
128 if (ret) 140 if (ret)
129 return ret; 141 return ret;
130 142
@@ -134,7 +146,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
134 return 0; 146 return 0;
135} 147}
136 148
137static struct file_operations ipoib_fops = { 149static struct file_operations ipoib_mcg_fops = {
138 .owner = THIS_MODULE, 150 .owner = THIS_MODULE,
139 .open = ipoib_mcg_open, 151 .open = ipoib_mcg_open,
140 .read = seq_read, 152 .read = seq_read,
@@ -142,25 +154,138 @@ static struct file_operations ipoib_fops = {
142 .release = seq_release 154 .release = seq_release
143}; 155};
144 156
145int ipoib_create_debug_file(struct net_device *dev) 157static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)
158{
159 struct ipoib_path_iter *iter;
160 loff_t n = *pos;
161
162 iter = ipoib_path_iter_init(file->private);
163 if (!iter)
164 return NULL;
165
166 while (n--) {
167 if (ipoib_path_iter_next(iter)) {
168 kfree(iter);
169 return NULL;
170 }
171 }
172
173 return iter;
174}
175
176static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,
177 loff_t *pos)
178{
179 struct ipoib_path_iter *iter = iter_ptr;
180
181 (*pos)++;
182
183 if (ipoib_path_iter_next(iter)) {
184 kfree(iter);
185 return NULL;
186 }
187
188 return iter;
189}
190
191static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)
192{
193 /* nothing for now */
194}
195
196static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
197{
198 struct ipoib_path_iter *iter = iter_ptr;
199 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
200 struct ipoib_path path;
201 int rate;
202
203 if (!iter)
204 return 0;
205
206 ipoib_path_iter_read(iter, &path);
207
208 format_gid(&path.pathrec.dgid, gid_buf);
209
210 seq_printf(file,
211 "GID: %s\n"
212 " complete: %6s\n",
213 gid_buf, path.pathrec.dlid ? "yes" : "no");
214
215 if (path.pathrec.dlid) {
216 rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25;
217
218 seq_printf(file,
219 " DLID: 0x%04x\n"
220 " SL: %12d\n"
221 " rate: %*d%s Gb/sec\n",
222 be16_to_cpu(path.pathrec.dlid),
223 path.pathrec.sl,
224 10 - ((rate % 10) ? 2 : 0),
225 rate / 10, rate % 10 ? ".5" : "");
226 }
227
228 seq_putc(file, '\n');
229
230 return 0;
231}
232
233static struct seq_operations ipoib_path_seq_ops = {
234 .start = ipoib_path_seq_start,
235 .next = ipoib_path_seq_next,
236 .stop = ipoib_path_seq_stop,
237 .show = ipoib_path_seq_show,
238};
239
240static int ipoib_path_open(struct inode *inode, struct file *file)
241{
242 struct seq_file *seq;
243 int ret;
244
245 ret = seq_open(file, &ipoib_path_seq_ops);
246 if (ret)
247 return ret;
248
249 seq = file->private_data;
250 seq->private = inode->u.generic_ip;
251
252 return 0;
253}
254
255static struct file_operations ipoib_path_fops = {
256 .owner = THIS_MODULE,
257 .open = ipoib_path_open,
258 .read = seq_read,
259 .llseek = seq_lseek,
260 .release = seq_release
261};
262
263void ipoib_create_debug_files(struct net_device *dev)
146{ 264{
147 struct ipoib_dev_priv *priv = netdev_priv(dev); 265 struct ipoib_dev_priv *priv = netdev_priv(dev);
148 char name[IFNAMSIZ + sizeof "_mcg"]; 266 char name[IFNAMSIZ + sizeof "_path"];
149 267
150 snprintf(name, sizeof name, "%s_mcg", dev->name); 268 snprintf(name, sizeof name, "%s_mcg", dev->name);
151
152 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, 269 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
153 ipoib_root, dev, &ipoib_fops); 270 ipoib_root, dev, &ipoib_mcg_fops);
154 271 if (!priv->mcg_dentry)
155 return priv->mcg_dentry ? 0 : -ENOMEM; 272 ipoib_warn(priv, "failed to create mcg debug file\n");
273
274 snprintf(name, sizeof name, "%s_path", dev->name);
275 priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
276 ipoib_root, dev, &ipoib_path_fops);
277 if (!priv->path_dentry)
278 ipoib_warn(priv, "failed to create path debug file\n");
156} 279}
157 280
158void ipoib_delete_debug_file(struct net_device *dev) 281void ipoib_delete_debug_files(struct net_device *dev)
159{ 282{
160 struct ipoib_dev_priv *priv = netdev_priv(dev); 283 struct ipoib_dev_priv *priv = netdev_priv(dev);
161 284
162 if (priv->mcg_dentry) 285 if (priv->mcg_dentry)
163 debugfs_remove(priv->mcg_dentry); 286 debugfs_remove(priv->mcg_dentry);
287 if (priv->path_dentry)
288 debugfs_remove(priv->path_dentry);
164} 289}
165 290
166int ipoib_register_debugfs(void) 291int ipoib_register_debugfs(void)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index ce0296273e76..2fa30751f362 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -58,6 +58,11 @@ module_param_named(debug_level, ipoib_debug_level, int, 0644);
58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); 58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
59#endif 59#endif
60 60
61struct ipoib_path_iter {
62 struct net_device *dev;
63 struct ipoib_path path;
64};
65
61static const u8 ipv4_bcast_addr[] = { 66static const u8 ipv4_bcast_addr[] = {
62 0x00, 0xff, 0xff, 0xff, 67 0x00, 0xff, 0xff, 0xff,
63 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00, 68 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
@@ -250,6 +255,64 @@ static void path_free(struct net_device *dev, struct ipoib_path *path)
250 kfree(path); 255 kfree(path);
251} 256}
252 257
258#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
259
260struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev)
261{
262 struct ipoib_path_iter *iter;
263
264 iter = kmalloc(sizeof *iter, GFP_KERNEL);
265 if (!iter)
266 return NULL;
267
268 iter->dev = dev;
269 memset(iter->path.pathrec.dgid.raw, 0, 16);
270
271 if (ipoib_path_iter_next(iter)) {
272 kfree(iter);
273 return NULL;
274 }
275
276 return iter;
277}
278
279int ipoib_path_iter_next(struct ipoib_path_iter *iter)
280{
281 struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
282 struct rb_node *n;
283 struct ipoib_path *path;
284 int ret = 1;
285
286 spin_lock_irq(&priv->lock);
287
288 n = rb_first(&priv->path_tree);
289
290 while (n) {
291 path = rb_entry(n, struct ipoib_path, rb_node);
292
293 if (memcmp(iter->path.pathrec.dgid.raw, path->pathrec.dgid.raw,
294 sizeof (union ib_gid)) < 0) {
295 iter->path = *path;
296 ret = 0;
297 break;
298 }
299
300 n = rb_next(n);
301 }
302
303 spin_unlock_irq(&priv->lock);
304
305 return ret;
306}
307
308void ipoib_path_iter_read(struct ipoib_path_iter *iter,
309 struct ipoib_path *path)
310{
311 *path = iter->path;
312}
313
314#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
315
253void ipoib_flush_paths(struct net_device *dev) 316void ipoib_flush_paths(struct net_device *dev)
254{ 317{
255 struct ipoib_dev_priv *priv = netdev_priv(dev); 318 struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -763,7 +826,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
763{ 826{
764 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv; 827 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv;
765 828
766 ipoib_delete_debug_file(dev); 829 ipoib_delete_debug_files(dev);
767 830
768 /* Delete any child interfaces first */ 831 /* Delete any child interfaces first */
769 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) { 832 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
@@ -972,8 +1035,7 @@ static struct net_device *ipoib_add_port(const char *format,
972 goto register_failed; 1035 goto register_failed;
973 } 1036 }
974 1037
975 if (ipoib_create_debug_file(priv->dev)) 1038 ipoib_create_debug_files(priv->dev);
976 goto debug_failed;
977 1039
978 if (ipoib_add_pkey_attr(priv->dev)) 1040 if (ipoib_add_pkey_attr(priv->dev))
979 goto sysfs_failed; 1041 goto sysfs_failed;
@@ -987,9 +1049,7 @@ static struct net_device *ipoib_add_port(const char *format,
987 return priv->dev; 1049 return priv->dev;
988 1050
989sysfs_failed: 1051sysfs_failed:
990 ipoib_delete_debug_file(priv->dev); 1052 ipoib_delete_debug_files(priv->dev);
991
992debug_failed:
993 unregister_netdev(priv->dev); 1053 unregister_netdev(priv->dev);
994 1054
995register_failed: 1055register_failed:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 3ecf78a9493a..c33ed87f9dff 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -120,12 +120,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
120 if (mcast->ah) 120 if (mcast->ah)
121 ipoib_put_ah(mcast->ah); 121 ipoib_put_ah(mcast->ah);
122 122
123 while (!skb_queue_empty(&mcast->pkt_queue)) { 123 while (!skb_queue_empty(&mcast->pkt_queue))
124 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 124 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
125
126 skb->dev = dev;
127 dev_kfree_skb_any(skb);
128 }
129 125
130 kfree(mcast); 126 kfree(mcast);
131} 127}
@@ -317,13 +313,8 @@ ipoib_mcast_sendonly_join_complete(int status,
317 IPOIB_GID_ARG(mcast->mcmember.mgid), status); 313 IPOIB_GID_ARG(mcast->mcmember.mgid), status);
318 314
319 /* Flush out any queued packets */ 315 /* Flush out any queued packets */
320 while (!skb_queue_empty(&mcast->pkt_queue)) { 316 while (!skb_queue_empty(&mcast->pkt_queue))
321 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 317 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
322
323 skb->dev = dev;
324
325 dev_kfree_skb_any(skb);
326 }
327 318
328 /* Clear the busy flag so we try again */ 319 /* Clear the busy flag so we try again */
329 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); 320 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
@@ -928,21 +919,16 @@ struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev)
928 return NULL; 919 return NULL;
929 920
930 iter->dev = dev; 921 iter->dev = dev;
931 memset(iter->mgid.raw, 0, sizeof iter->mgid); 922 memset(iter->mgid.raw, 0, 16);
932 923
933 if (ipoib_mcast_iter_next(iter)) { 924 if (ipoib_mcast_iter_next(iter)) {
934 ipoib_mcast_iter_free(iter); 925 kfree(iter);
935 return NULL; 926 return NULL;
936 } 927 }
937 928
938 return iter; 929 return iter;
939} 930}
940 931
941void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter)
942{
943 kfree(iter);
944}
945
946int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter) 932int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter)
947{ 933{
948 struct ipoib_dev_priv *priv = netdev_priv(iter->dev); 934 struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 332d730e60c2..d280b341a37f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -113,8 +113,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
113 113
114 priv->parent = ppriv->dev; 114 priv->parent = ppriv->dev;
115 115
116 if (ipoib_create_debug_file(priv->dev)) 116 ipoib_create_debug_files(priv->dev);
117 goto debug_failed;
118 117
119 if (ipoib_add_pkey_attr(priv->dev)) 118 if (ipoib_add_pkey_attr(priv->dev))
120 goto sysfs_failed; 119 goto sysfs_failed;
@@ -130,9 +129,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
130 return 0; 129 return 0;
131 130
132sysfs_failed: 131sysfs_failed:
133 ipoib_delete_debug_file(priv->dev); 132 ipoib_delete_debug_files(priv->dev);
134
135debug_failed:
136 unregister_netdev(priv->dev); 133 unregister_netdev(priv->dev);
137 134
138register_failed: 135register_failed: