aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2011-06-02 12:01:33 -0400
committerRoland Dreier <roland@purestorage.com>2011-10-13 12:43:03 -0400
commit012a8ff577f95211c6ffd3b77a94c34ebae009b6 (patch)
tree7d1e8d3ca131cc46ca12e879c4554870e0be76f2 /drivers
parent2622e18ef407a8e8e3ddc3d6f0c77b756c493798 (diff)
IB/mlx4: Add support for XRC domains
Support creating and destroying XRC domains. Any sharing of the XRCD is managed above the low-level driver. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/mlx4/main.c59
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h12
-rw-r--r--drivers/net/mlx4/fw.c6
-rw-r--r--drivers/net/mlx4/fw.h2
-rw-r--r--drivers/net/mlx4/main.c18
-rw-r--r--drivers/net/mlx4/mlx4.h3
-rw-r--r--drivers/net/mlx4/pd.c30
7 files changed, 129 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index fa643f4f4e28..23e45df9ae36 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -566,6 +566,57 @@ static int mlx4_ib_dealloc_pd(struct ib_pd *pd)
566 return 0; 566 return 0;
567} 567}
568 568
569static struct ib_xrcd *mlx4_ib_alloc_xrcd(struct ib_device *ibdev,
570 struct ib_ucontext *context,
571 struct ib_udata *udata)
572{
573 struct mlx4_ib_xrcd *xrcd;
574 int err;
575
576 if (!(to_mdev(ibdev)->dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC))
577 return ERR_PTR(-ENOSYS);
578
579 xrcd = kmalloc(sizeof *xrcd, GFP_KERNEL);
580 if (!xrcd)
581 return ERR_PTR(-ENOMEM);
582
583 err = mlx4_xrcd_alloc(to_mdev(ibdev)->dev, &xrcd->xrcdn);
584 if (err)
585 goto err1;
586
587 xrcd->pd = ib_alloc_pd(ibdev);
588 if (IS_ERR(xrcd->pd)) {
589 err = PTR_ERR(xrcd->pd);
590 goto err2;
591 }
592
593 xrcd->cq = ib_create_cq(ibdev, NULL, NULL, xrcd, 1, 0);
594 if (IS_ERR(xrcd->cq)) {
595 err = PTR_ERR(xrcd->cq);
596 goto err3;
597 }
598
599 return &xrcd->ibxrcd;
600
601err3:
602 ib_dealloc_pd(xrcd->pd);
603err2:
604 mlx4_xrcd_free(to_mdev(ibdev)->dev, xrcd->xrcdn);
605err1:
606 kfree(xrcd);
607 return ERR_PTR(err);
608}
609
610static int mlx4_ib_dealloc_xrcd(struct ib_xrcd *xrcd)
611{
612 ib_destroy_cq(to_mxrcd(xrcd)->cq);
613 ib_dealloc_pd(to_mxrcd(xrcd)->pd);
614 mlx4_xrcd_free(to_mdev(xrcd->device)->dev, to_mxrcd(xrcd)->xrcdn);
615 kfree(xrcd);
616
617 return 0;
618}
619
569static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid) 620static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid)
570{ 621{
571 struct mlx4_ib_qp *mqp = to_mqp(ibqp); 622 struct mlx4_ib_qp *mqp = to_mqp(ibqp);
@@ -1093,6 +1144,14 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
1093 ibdev->ib_dev.unmap_fmr = mlx4_ib_unmap_fmr; 1144 ibdev->ib_dev.unmap_fmr = mlx4_ib_unmap_fmr;
1094 ibdev->ib_dev.dealloc_fmr = mlx4_ib_fmr_dealloc; 1145 ibdev->ib_dev.dealloc_fmr = mlx4_ib_fmr_dealloc;
1095 1146
1147 if (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) {
1148 ibdev->ib_dev.alloc_xrcd = mlx4_ib_alloc_xrcd;
1149 ibdev->ib_dev.dealloc_xrcd = mlx4_ib_dealloc_xrcd;
1150 ibdev->ib_dev.uverbs_cmd_mask |=
1151 (1ull << IB_USER_VERBS_CMD_OPEN_XRCD) |
1152 (1ull << IB_USER_VERBS_CMD_CLOSE_XRCD);
1153 }
1154
1096 spin_lock_init(&iboe->lock); 1155 spin_lock_init(&iboe->lock);
1097 1156
1098 if (init_node_data(ibdev)) 1157 if (init_node_data(ibdev))
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index e4bf2cff8662..ce150b0e2cc8 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -56,6 +56,13 @@ struct mlx4_ib_pd {
56 u32 pdn; 56 u32 pdn;
57}; 57};
58 58
59struct mlx4_ib_xrcd {
60 struct ib_xrcd ibxrcd;
61 u32 xrcdn;
62 struct ib_pd *pd;
63 struct ib_cq *cq;
64};
65
59struct mlx4_ib_cq_buf { 66struct mlx4_ib_cq_buf {
60 struct mlx4_buf buf; 67 struct mlx4_buf buf;
61 struct mlx4_mtt mtt; 68 struct mlx4_mtt mtt;
@@ -211,6 +218,11 @@ static inline struct mlx4_ib_pd *to_mpd(struct ib_pd *ibpd)
211 return container_of(ibpd, struct mlx4_ib_pd, ibpd); 218 return container_of(ibpd, struct mlx4_ib_pd, ibpd);
212} 219}
213 220
221static inline struct mlx4_ib_xrcd *to_mxrcd(struct ib_xrcd *ibxrcd)
222{
223 return container_of(ibxrcd, struct mlx4_ib_xrcd, ibxrcd);
224}
225
214static inline struct mlx4_ib_cq *to_mcq(struct ib_cq *ibcq) 226static inline struct mlx4_ib_cq *to_mcq(struct ib_cq *ibcq)
215{ 227{
216 return container_of(ibcq, struct mlx4_ib_cq, ibcq); 228 return container_of(ibcq, struct mlx4_ib_cq, ibcq);
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index 7eb8ba822e97..875838b8799c 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -204,6 +204,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
204#define QUERY_DEV_CAP_MAX_MCG_OFFSET 0x63 204#define QUERY_DEV_CAP_MAX_MCG_OFFSET 0x63
205#define QUERY_DEV_CAP_RSVD_PD_OFFSET 0x64 205#define QUERY_DEV_CAP_RSVD_PD_OFFSET 0x64
206#define QUERY_DEV_CAP_MAX_PD_OFFSET 0x65 206#define QUERY_DEV_CAP_MAX_PD_OFFSET 0x65
207#define QUERY_DEV_CAP_RSVD_XRC_OFFSET 0x66
208#define QUERY_DEV_CAP_MAX_XRC_OFFSET 0x67
207#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68 209#define QUERY_DEV_CAP_MAX_COUNTERS_OFFSET 0x68
208#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80 210#define QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET 0x80
209#define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82 211#define QUERY_DEV_CAP_QPC_ENTRY_SZ_OFFSET 0x82
@@ -318,6 +320,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
318 dev_cap->reserved_pds = field >> 4; 320 dev_cap->reserved_pds = field >> 4;
319 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PD_OFFSET); 321 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PD_OFFSET);
320 dev_cap->max_pds = 1 << (field & 0x3f); 322 dev_cap->max_pds = 1 << (field & 0x3f);
323 MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_XRC_OFFSET);
324 dev_cap->reserved_xrcds = field >> 4;
325 MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_PD_OFFSET);
326 dev_cap->max_xrcds = 1 << (field & 0x1f);
321 327
322 MLX4_GET(size, outbox, QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET); 328 MLX4_GET(size, outbox, QUERY_DEV_CAP_RDMARC_ENTRY_SZ_OFFSET);
323 dev_cap->rdmarc_entry_sz = size; 329 dev_cap->rdmarc_entry_sz = size;
diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h
index 1e8ecc3708e2..bf5ec2286528 100644
--- a/drivers/net/mlx4/fw.h
+++ b/drivers/net/mlx4/fw.h
@@ -93,6 +93,8 @@ struct mlx4_dev_cap {
93 int max_mcgs; 93 int max_mcgs;
94 int reserved_pds; 94 int reserved_pds;
95 int max_pds; 95 int max_pds;
96 int reserved_xrcds;
97 int max_xrcds;
96 int qpc_entry_sz; 98 int qpc_entry_sz;
97 int rdmarc_entry_sz; 99 int rdmarc_entry_sz;
98 int altc_entry_sz; 100 int altc_entry_sz;
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index f0ee35df4dd7..660b691ede76 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -220,6 +220,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
220 dev->caps.reserved_mrws = dev_cap->reserved_mrws; 220 dev->caps.reserved_mrws = dev_cap->reserved_mrws;
221 dev->caps.reserved_uars = dev_cap->reserved_uars; 221 dev->caps.reserved_uars = dev_cap->reserved_uars;
222 dev->caps.reserved_pds = dev_cap->reserved_pds; 222 dev->caps.reserved_pds = dev_cap->reserved_pds;
223 dev->caps.reserved_xrcds = (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) ?
224 dev_cap->reserved_xrcds : 0;
225 dev->caps.max_xrcds = (dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC) ?
226 dev_cap->max_xrcds : 0;
223 dev->caps.mtt_entry_sz = dev->caps.mtts_per_seg * dev_cap->mtt_entry_sz; 227 dev->caps.mtt_entry_sz = dev->caps.mtts_per_seg * dev_cap->mtt_entry_sz;
224 dev->caps.max_msg_sz = dev_cap->max_msg_sz; 228 dev->caps.max_msg_sz = dev_cap->max_msg_sz;
225 dev->caps.page_size_cap = ~(u32) (dev_cap->min_page_sz - 1); 229 dev->caps.page_size_cap = ~(u32) (dev_cap->min_page_sz - 1);
@@ -912,11 +916,18 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
912 goto err_kar_unmap; 916 goto err_kar_unmap;
913 } 917 }
914 918
919 err = mlx4_init_xrcd_table(dev);
920 if (err) {
921 mlx4_err(dev, "Failed to initialize "
922 "reliable connection domain table, aborting.\n");
923 goto err_pd_table_free;
924 }
925
915 err = mlx4_init_mr_table(dev); 926 err = mlx4_init_mr_table(dev);
916 if (err) { 927 if (err) {
917 mlx4_err(dev, "Failed to initialize " 928 mlx4_err(dev, "Failed to initialize "
918 "memory region table, aborting.\n"); 929 "memory region table, aborting.\n");
919 goto err_pd_table_free; 930 goto err_xrcd_table_free;
920 } 931 }
921 932
922 err = mlx4_init_eq_table(dev); 933 err = mlx4_init_eq_table(dev);
@@ -1033,6 +1044,9 @@ err_eq_table_free:
1033err_mr_table_free: 1044err_mr_table_free:
1034 mlx4_cleanup_mr_table(dev); 1045 mlx4_cleanup_mr_table(dev);
1035 1046
1047err_xrcd_table_free:
1048 mlx4_cleanup_xrcd_table(dev);
1049
1036err_pd_table_free: 1050err_pd_table_free:
1037 mlx4_cleanup_pd_table(dev); 1051 mlx4_cleanup_pd_table(dev);
1038 1052
@@ -1355,6 +1369,7 @@ err_port:
1355 mlx4_cmd_use_polling(dev); 1369 mlx4_cmd_use_polling(dev);
1356 mlx4_cleanup_eq_table(dev); 1370 mlx4_cleanup_eq_table(dev);
1357 mlx4_cleanup_mr_table(dev); 1371 mlx4_cleanup_mr_table(dev);
1372 mlx4_cleanup_xrcd_table(dev);
1358 mlx4_cleanup_pd_table(dev); 1373 mlx4_cleanup_pd_table(dev);
1359 mlx4_cleanup_uar_table(dev); 1374 mlx4_cleanup_uar_table(dev);
1360 1375
@@ -1416,6 +1431,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
1416 mlx4_cmd_use_polling(dev); 1431 mlx4_cmd_use_polling(dev);
1417 mlx4_cleanup_eq_table(dev); 1432 mlx4_cleanup_eq_table(dev);
1418 mlx4_cleanup_mr_table(dev); 1433 mlx4_cleanup_mr_table(dev);
1434 mlx4_cleanup_xrcd_table(dev);
1419 mlx4_cleanup_pd_table(dev); 1435 mlx4_cleanup_pd_table(dev);
1420 1436
1421 iounmap(priv->kar); 1437 iounmap(priv->kar);
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index a2fcd8402d37..fee2d05aa1dc 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -335,6 +335,7 @@ struct mlx4_priv {
335 struct mlx4_cmd cmd; 335 struct mlx4_cmd cmd;
336 336
337 struct mlx4_bitmap pd_bitmap; 337 struct mlx4_bitmap pd_bitmap;
338 struct mlx4_bitmap xrcd_bitmap;
338 struct mlx4_uar_table uar_table; 339 struct mlx4_uar_table uar_table;
339 struct mlx4_mr_table mr_table; 340 struct mlx4_mr_table mr_table;
340 struct mlx4_cq_table cq_table; 341 struct mlx4_cq_table cq_table;
@@ -384,6 +385,7 @@ int mlx4_alloc_eq_table(struct mlx4_dev *dev);
384void mlx4_free_eq_table(struct mlx4_dev *dev); 385void mlx4_free_eq_table(struct mlx4_dev *dev);
385 386
386int mlx4_init_pd_table(struct mlx4_dev *dev); 387int mlx4_init_pd_table(struct mlx4_dev *dev);
388int mlx4_init_xrcd_table(struct mlx4_dev *dev);
387int mlx4_init_uar_table(struct mlx4_dev *dev); 389int mlx4_init_uar_table(struct mlx4_dev *dev);
388int mlx4_init_mr_table(struct mlx4_dev *dev); 390int mlx4_init_mr_table(struct mlx4_dev *dev);
389int mlx4_init_eq_table(struct mlx4_dev *dev); 391int mlx4_init_eq_table(struct mlx4_dev *dev);
@@ -393,6 +395,7 @@ int mlx4_init_srq_table(struct mlx4_dev *dev);
393int mlx4_init_mcg_table(struct mlx4_dev *dev); 395int mlx4_init_mcg_table(struct mlx4_dev *dev);
394 396
395void mlx4_cleanup_pd_table(struct mlx4_dev *dev); 397void mlx4_cleanup_pd_table(struct mlx4_dev *dev);
398void mlx4_cleanup_xrcd_table(struct mlx4_dev *dev);
396void mlx4_cleanup_uar_table(struct mlx4_dev *dev); 399void mlx4_cleanup_uar_table(struct mlx4_dev *dev);
397void mlx4_cleanup_mr_table(struct mlx4_dev *dev); 400void mlx4_cleanup_mr_table(struct mlx4_dev *dev);
398void mlx4_cleanup_eq_table(struct mlx4_dev *dev); 401void mlx4_cleanup_eq_table(struct mlx4_dev *dev);
diff --git a/drivers/net/mlx4/pd.c b/drivers/net/mlx4/pd.c
index 1286b886dcea..3736163e30e9 100644
--- a/drivers/net/mlx4/pd.c
+++ b/drivers/net/mlx4/pd.c
@@ -61,6 +61,24 @@ void mlx4_pd_free(struct mlx4_dev *dev, u32 pdn)
61} 61}
62EXPORT_SYMBOL_GPL(mlx4_pd_free); 62EXPORT_SYMBOL_GPL(mlx4_pd_free);
63 63
64int mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn)
65{
66 struct mlx4_priv *priv = mlx4_priv(dev);
67
68 *xrcdn = mlx4_bitmap_alloc(&priv->xrcd_bitmap);
69 if (*xrcdn == -1)
70 return -ENOMEM;
71
72 return 0;
73}
74EXPORT_SYMBOL_GPL(mlx4_xrcd_alloc);
75
76void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
77{
78 mlx4_bitmap_free(&mlx4_priv(dev)->xrcd_bitmap, xrcdn);
79}
80EXPORT_SYMBOL_GPL(mlx4_xrcd_free);
81
64int mlx4_init_pd_table(struct mlx4_dev *dev) 82int mlx4_init_pd_table(struct mlx4_dev *dev)
65{ 83{
66 struct mlx4_priv *priv = mlx4_priv(dev); 84 struct mlx4_priv *priv = mlx4_priv(dev);
@@ -74,6 +92,18 @@ void mlx4_cleanup_pd_table(struct mlx4_dev *dev)
74 mlx4_bitmap_cleanup(&mlx4_priv(dev)->pd_bitmap); 92 mlx4_bitmap_cleanup(&mlx4_priv(dev)->pd_bitmap);
75} 93}
76 94
95int mlx4_init_xrcd_table(struct mlx4_dev *dev)
96{
97 struct mlx4_priv *priv = mlx4_priv(dev);
98
99 return mlx4_bitmap_init(&priv->xrcd_bitmap, (1 << 16),
100 (1 << 16) - 1, dev->caps.reserved_xrcds + 1, 0);
101}
102
103void mlx4_cleanup_xrcd_table(struct mlx4_dev *dev)
104{
105 mlx4_bitmap_cleanup(&mlx4_priv(dev)->xrcd_bitmap);
106}
77 107
78int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar) 108int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar)
79{ 109{