aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mthca
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-21 19:19:32 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-21 19:19:32 -0400
commit8aee74c8ee875448cc6d1cf995c9469eb60ae515 (patch)
tree9e9f57dd7fe321825d7e39472cf44777c82f39cf /drivers/infiniband/hw/mthca
parent080e89270a7bfb7d01fac9a67050f8ac6d6cdd11 (diff)
parent9f81036c54ed1f860d2807c5a6aa4f2b30c21204 (diff)
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband: IB/cm: Improve local id allocation IPoIB/cm: Fix SRQ WR leak IB/ipoib: Fix typos in error messages IB/mlx4: Check if SRQ is full when posting receive IB/mlx4: Pass send queue sizes from userspace to kernel IB/mlx4: Fix check of opcode in mlx4_ib_post_send() mlx4_core: Fix array overrun in dump_dev_cap_flags() IB/mlx4: Fix RESET to RESET and RESET to ERROR transitions IB/mthca: Fix RESET to ERROR transition IB/mlx4: Set GRH:HopLimit when sending globally routed MADs IB/mthca: Set GRH:HopLimit when building MLX headers IB/mlx4: Fix check of max_qp_dest_rdma in modify QP IB/mthca: Fix use-after-free on device restart IB/ehca: Return proper error code if register_mr fails IPoIB: Handle P_Key table reordering IB/core: Use start_port() and end_port() IB/core: Add helpers for uncached GID and P_Key searches IB/ipath: Fix potential deadlock with multicast spinlocks IB/core: Free umem when mm is already gone
Diffstat (limited to 'drivers/infiniband/hw/mthca')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c158
3 files changed, 102 insertions, 61 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index 27caf3b0648a..4b111a852ff6 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -279,6 +279,7 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah,
279 (be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20) & 0xff; 279 (be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20) & 0xff;
280 header->grh.flow_label = 280 header->grh.flow_label =
281 ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff); 281 ah->av->sl_tclass_flowlabel & cpu_to_be32(0xfffff);
282 header->grh.hop_limit = ah->av->hop_limit;
282 ib_get_cached_gid(&dev->ib_dev, 283 ib_get_cached_gid(&dev->ib_dev,
283 be32_to_cpu(ah->av->port_pd) >> 24, 284 be32_to_cpu(ah->av->port_pd) >> 24,
284 ah->av->gid_index % dev->limits.gid_table_len, 285 ah->av->gid_index % dev->limits.gid_table_len,
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 773145e29947..aa563e61de65 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -1250,12 +1250,14 @@ static void __mthca_remove_one(struct pci_dev *pdev)
1250int __mthca_restart_one(struct pci_dev *pdev) 1250int __mthca_restart_one(struct pci_dev *pdev)
1251{ 1251{
1252 struct mthca_dev *mdev; 1252 struct mthca_dev *mdev;
1253 int hca_type;
1253 1254
1254 mdev = pci_get_drvdata(pdev); 1255 mdev = pci_get_drvdata(pdev);
1255 if (!mdev) 1256 if (!mdev)
1256 return -ENODEV; 1257 return -ENODEV;
1258 hca_type = mdev->hca_type;
1257 __mthca_remove_one(pdev); 1259 __mthca_remove_one(pdev);
1258 return __mthca_init_one(pdev, mdev->hca_type); 1260 return __mthca_init_one(pdev, hca_type);
1259} 1261}
1260 1262
1261static int __devinit mthca_init_one(struct pci_dev *pdev, 1263static int __devinit mthca_init_one(struct pci_dev *pdev,
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 2741ded89297..027664979fe2 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -296,7 +296,7 @@ static int to_mthca_st(int transport)
296 } 296 }
297} 297}
298 298
299static void store_attrs(struct mthca_sqp *sqp, struct ib_qp_attr *attr, 299static void store_attrs(struct mthca_sqp *sqp, const struct ib_qp_attr *attr,
300 int attr_mask) 300 int attr_mask)
301{ 301{
302 if (attr_mask & IB_QP_PKEY_INDEX) 302 if (attr_mask & IB_QP_PKEY_INDEX)
@@ -328,7 +328,7 @@ static void init_port(struct mthca_dev *dev, int port)
328 mthca_warn(dev, "INIT_IB returned status %02x.\n", status); 328 mthca_warn(dev, "INIT_IB returned status %02x.\n", status);
329} 329}
330 330
331static __be32 get_hw_access_flags(struct mthca_qp *qp, struct ib_qp_attr *attr, 331static __be32 get_hw_access_flags(struct mthca_qp *qp, const struct ib_qp_attr *attr,
332 int attr_mask) 332 int attr_mask)
333{ 333{
334 u8 dest_rd_atomic; 334 u8 dest_rd_atomic;
@@ -511,7 +511,7 @@ out:
511 return err; 511 return err;
512} 512}
513 513
514static int mthca_path_set(struct mthca_dev *dev, struct ib_ah_attr *ah, 514static int mthca_path_set(struct mthca_dev *dev, const struct ib_ah_attr *ah,
515 struct mthca_qp_path *path, u8 port) 515 struct mthca_qp_path *path, u8 port)
516{ 516{
517 path->g_mylmc = ah->src_path_bits & 0x7f; 517 path->g_mylmc = ah->src_path_bits & 0x7f;
@@ -539,12 +539,12 @@ static int mthca_path_set(struct mthca_dev *dev, struct ib_ah_attr *ah,
539 return 0; 539 return 0;
540} 540}
541 541
542int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, 542static int __mthca_modify_qp(struct ib_qp *ibqp,
543 struct ib_udata *udata) 543 const struct ib_qp_attr *attr, int attr_mask,
544 enum ib_qp_state cur_state, enum ib_qp_state new_state)
544{ 545{
545 struct mthca_dev *dev = to_mdev(ibqp->device); 546 struct mthca_dev *dev = to_mdev(ibqp->device);
546 struct mthca_qp *qp = to_mqp(ibqp); 547 struct mthca_qp *qp = to_mqp(ibqp);
547 enum ib_qp_state cur_state, new_state;
548 struct mthca_mailbox *mailbox; 548 struct mthca_mailbox *mailbox;
549 struct mthca_qp_param *qp_param; 549 struct mthca_qp_param *qp_param;
550 struct mthca_qp_context *qp_context; 550 struct mthca_qp_context *qp_context;
@@ -552,60 +552,6 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
552 u8 status; 552 u8 status;
553 int err = -EINVAL; 553 int err = -EINVAL;
554 554
555 mutex_lock(&qp->mutex);
556
557 if (attr_mask & IB_QP_CUR_STATE) {
558 cur_state = attr->cur_qp_state;
559 } else {
560 spin_lock_irq(&qp->sq.lock);
561 spin_lock(&qp->rq.lock);
562 cur_state = qp->state;
563 spin_unlock(&qp->rq.lock);
564 spin_unlock_irq(&qp->sq.lock);
565 }
566
567 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
568
569 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) {
570 mthca_dbg(dev, "Bad QP transition (transport %d) "
571 "%d->%d with attr 0x%08x\n",
572 qp->transport, cur_state, new_state,
573 attr_mask);
574 goto out;
575 }
576
577 if (cur_state == new_state && cur_state == IB_QPS_RESET) {
578 err = 0;
579 goto out;
580 }
581
582 if ((attr_mask & IB_QP_PKEY_INDEX) &&
583 attr->pkey_index >= dev->limits.pkey_table_len) {
584 mthca_dbg(dev, "P_Key index (%u) too large. max is %d\n",
585 attr->pkey_index, dev->limits.pkey_table_len-1);
586 goto out;
587 }
588
589 if ((attr_mask & IB_QP_PORT) &&
590 (attr->port_num == 0 || attr->port_num > dev->limits.num_ports)) {
591 mthca_dbg(dev, "Port number (%u) is invalid\n", attr->port_num);
592 goto out;
593 }
594
595 if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
596 attr->max_rd_atomic > dev->limits.max_qp_init_rdma) {
597 mthca_dbg(dev, "Max rdma_atomic as initiator %u too large (max is %d)\n",
598 attr->max_rd_atomic, dev->limits.max_qp_init_rdma);
599 goto out;
600 }
601
602 if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
603 attr->max_dest_rd_atomic > 1 << dev->qp_table.rdb_shift) {
604 mthca_dbg(dev, "Max rdma_atomic as responder %u too large (max %d)\n",
605 attr->max_dest_rd_atomic, 1 << dev->qp_table.rdb_shift);
606 goto out;
607 }
608
609 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); 555 mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
610 if (IS_ERR(mailbox)) { 556 if (IS_ERR(mailbox)) {
611 err = PTR_ERR(mailbox); 557 err = PTR_ERR(mailbox);
@@ -892,6 +838,98 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
892 838
893out_mailbox: 839out_mailbox:
894 mthca_free_mailbox(dev, mailbox); 840 mthca_free_mailbox(dev, mailbox);
841out:
842 return err;
843}
844
845static const struct ib_qp_attr dummy_init_attr = { .port_num = 1 };
846static const int dummy_init_attr_mask[] = {
847 [IB_QPT_UD] = (IB_QP_PKEY_INDEX |
848 IB_QP_PORT |
849 IB_QP_QKEY),
850 [IB_QPT_UC] = (IB_QP_PKEY_INDEX |
851 IB_QP_PORT |
852 IB_QP_ACCESS_FLAGS),
853 [IB_QPT_RC] = (IB_QP_PKEY_INDEX |
854 IB_QP_PORT |
855 IB_QP_ACCESS_FLAGS),
856 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX |
857 IB_QP_QKEY),
858 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX |
859 IB_QP_QKEY),
860};
861
862int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
863 struct ib_udata *udata)
864{
865 struct mthca_dev *dev = to_mdev(ibqp->device);
866 struct mthca_qp *qp = to_mqp(ibqp);
867 enum ib_qp_state cur_state, new_state;
868 int err = -EINVAL;
869
870 mutex_lock(&qp->mutex);
871 if (attr_mask & IB_QP_CUR_STATE) {
872 cur_state = attr->cur_qp_state;
873 } else {
874 spin_lock_irq(&qp->sq.lock);
875 spin_lock(&qp->rq.lock);
876 cur_state = qp->state;
877 spin_unlock(&qp->rq.lock);
878 spin_unlock_irq(&qp->sq.lock);
879 }
880
881 new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
882
883 if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) {
884 mthca_dbg(dev, "Bad QP transition (transport %d) "
885 "%d->%d with attr 0x%08x\n",
886 qp->transport, cur_state, new_state,
887 attr_mask);
888 goto out;
889 }
890
891 if ((attr_mask & IB_QP_PKEY_INDEX) &&
892 attr->pkey_index >= dev->limits.pkey_table_len) {
893 mthca_dbg(dev, "P_Key index (%u) too large. max is %d\n",
894 attr->pkey_index, dev->limits.pkey_table_len-1);
895 goto out;
896 }
897
898 if ((attr_mask & IB_QP_PORT) &&
899 (attr->port_num == 0 || attr->port_num > dev->limits.num_ports)) {
900 mthca_dbg(dev, "Port number (%u) is invalid\n", attr->port_num);
901 goto out;
902 }
903
904 if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&
905 attr->max_rd_atomic > dev->limits.max_qp_init_rdma) {
906 mthca_dbg(dev, "Max rdma_atomic as initiator %u too large (max is %d)\n",
907 attr->max_rd_atomic, dev->limits.max_qp_init_rdma);
908 goto out;
909 }
910
911 if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&
912 attr->max_dest_rd_atomic > 1 << dev->qp_table.rdb_shift) {
913 mthca_dbg(dev, "Max rdma_atomic as responder %u too large (max %d)\n",
914 attr->max_dest_rd_atomic, 1 << dev->qp_table.rdb_shift);
915 goto out;
916 }
917
918 if (cur_state == new_state && cur_state == IB_QPS_RESET) {
919 err = 0;
920 goto out;
921 }
922
923 if (cur_state == IB_QPS_RESET && new_state == IB_QPS_ERR) {
924 err = __mthca_modify_qp(ibqp, &dummy_init_attr,
925 dummy_init_attr_mask[ibqp->qp_type],
926 IB_QPS_RESET, IB_QPS_INIT);
927 if (err)
928 goto out;
929 cur_state = IB_QPS_INIT;
930 }
931
932 err = __mthca_modify_qp(ibqp, attr, attr_mask, cur_state, new_state);
895 933
896out: 934out:
897 mutex_unlock(&qp->mutex); 935 mutex_unlock(&qp->mutex);