diff options
author | Ron Livne <ronli@voltaire.com> | 2008-07-15 02:48:48 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-07-15 02:48:48 -0400 |
commit | 521e575b9a7324a0bca762622139f69582a042bf (patch) | |
tree | 5962695835c6d11b424d76c64421ebd436b52a34 | |
parent | 47ee1b9f2e7bf73950602efe0b74fa1a8481f222 (diff) |
IB/mlx4: Add support for blocking multicast loopback packets
Add support for handling the IB_QP_CREATE_MULTICAST_BLOCK_LOOPBACK
flag by using the per-multicast group loopback blocking feature of
mlx4 hardware.
Signed-off-by: Ron Livne <ronli@voltaire.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | drivers/infiniband/hw/mlx4/main.c | 7 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/mlx4_ib.h | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx4/qp.c | 21 | ||||
-rw-r--r-- | drivers/net/mlx4/mcg.c | 17 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 3 |
5 files changed, 40 insertions, 11 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 4d61e32866c6..bcf50648fa18 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -90,7 +90,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, | |||
90 | props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT | | 90 | props->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT | |
91 | IB_DEVICE_PORT_ACTIVE_EVENT | | 91 | IB_DEVICE_PORT_ACTIVE_EVENT | |
92 | IB_DEVICE_SYS_IMAGE_GUID | | 92 | IB_DEVICE_SYS_IMAGE_GUID | |
93 | IB_DEVICE_RC_RNR_NAK_GEN; | 93 | IB_DEVICE_RC_RNR_NAK_GEN | |
94 | IB_DEVICE_BLOCK_MULTICAST_LOOPBACK; | ||
94 | if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR) | 95 | if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR) |
95 | props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR; | 96 | props->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR; |
96 | if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR) | 97 | if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR) |
@@ -437,7 +438,9 @@ static int mlx4_ib_dealloc_pd(struct ib_pd *pd) | |||
437 | static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | 438 | static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) |
438 | { | 439 | { |
439 | return mlx4_multicast_attach(to_mdev(ibqp->device)->dev, | 440 | return mlx4_multicast_attach(to_mdev(ibqp->device)->dev, |
440 | &to_mqp(ibqp)->mqp, gid->raw); | 441 | &to_mqp(ibqp)->mqp, gid->raw, |
442 | !!(to_mqp(ibqp)->flags & | ||
443 | MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK)); | ||
441 | } | 444 | } |
442 | 445 | ||
443 | static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) | 446 | static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 5cf994794d25..c4cf5b69eefa 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
@@ -101,7 +101,8 @@ struct mlx4_ib_wq { | |||
101 | }; | 101 | }; |
102 | 102 | ||
103 | enum mlx4_ib_qp_flags { | 103 | enum mlx4_ib_qp_flags { |
104 | MLX4_IB_QP_LSO = 1 << 0 | 104 | MLX4_IB_QP_LSO = 1 << 0, |
105 | MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = 1 << 1, | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | struct mlx4_ib_qp { | 108 | struct mlx4_ib_qp { |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 44bbd6c2e315..91590e7fba0c 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -511,6 +511,9 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, | |||
511 | } else { | 511 | } else { |
512 | qp->sq_no_prefetch = 0; | 512 | qp->sq_no_prefetch = 0; |
513 | 513 | ||
514 | if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) | ||
515 | qp->flags |= MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK; | ||
516 | |||
514 | if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) | 517 | if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) |
515 | qp->flags |= MLX4_IB_QP_LSO; | 518 | qp->flags |= MLX4_IB_QP_LSO; |
516 | 519 | ||
@@ -684,10 +687,15 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd, | |||
684 | struct mlx4_ib_qp *qp; | 687 | struct mlx4_ib_qp *qp; |
685 | int err; | 688 | int err; |
686 | 689 | ||
687 | /* We only support LSO, and only for kernel UD QPs. */ | 690 | /* |
688 | if (init_attr->create_flags & ~IB_QP_CREATE_IPOIB_UD_LSO) | 691 | * We only support LSO and multicast loopback blocking, and |
692 | * only for kernel UD QPs. | ||
693 | */ | ||
694 | if (init_attr->create_flags & ~(IB_QP_CREATE_IPOIB_UD_LSO | | ||
695 | IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)) | ||
689 | return ERR_PTR(-EINVAL); | 696 | return ERR_PTR(-EINVAL); |
690 | if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO && | 697 | |
698 | if (init_attr->create_flags && | ||
691 | (pd->uobject || init_attr->qp_type != IB_QPT_UD)) | 699 | (pd->uobject || init_attr->qp_type != IB_QPT_UD)) |
692 | return ERR_PTR(-EINVAL); | 700 | return ERR_PTR(-EINVAL); |
693 | 701 | ||
@@ -1844,6 +1852,13 @@ done: | |||
1844 | 1852 | ||
1845 | qp_init_attr->cap = qp_attr->cap; | 1853 | qp_init_attr->cap = qp_attr->cap; |
1846 | 1854 | ||
1855 | qp_init_attr->create_flags = 0; | ||
1856 | if (qp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK) | ||
1857 | qp_init_attr->create_flags |= IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK; | ||
1858 | |||
1859 | if (qp->flags & MLX4_IB_QP_LSO) | ||
1860 | qp_init_attr->create_flags |= IB_QP_CREATE_IPOIB_UD_LSO; | ||
1861 | |||
1847 | out: | 1862 | out: |
1848 | mutex_unlock(&qp->mutex); | 1863 | mutex_unlock(&qp->mutex); |
1849 | return err; | 1864 | return err; |
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c index 57f7f1f0d4ec..b4b57870ddfd 100644 --- a/drivers/net/mlx4/mcg.c +++ b/drivers/net/mlx4/mcg.c | |||
@@ -38,6 +38,9 @@ | |||
38 | 38 | ||
39 | #include "mlx4.h" | 39 | #include "mlx4.h" |
40 | 40 | ||
41 | #define MGM_QPN_MASK 0x00FFFFFF | ||
42 | #define MGM_BLCK_LB_BIT 30 | ||
43 | |||
41 | struct mlx4_mgm { | 44 | struct mlx4_mgm { |
42 | __be32 next_gid_index; | 45 | __be32 next_gid_index; |
43 | __be32 members_count; | 46 | __be32 members_count; |
@@ -153,7 +156,8 @@ static int find_mgm(struct mlx4_dev *dev, | |||
153 | return err; | 156 | return err; |
154 | } | 157 | } |
155 | 158 | ||
156 | int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) | 159 | int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], |
160 | int block_mcast_loopback) | ||
157 | { | 161 | { |
158 | struct mlx4_priv *priv = mlx4_priv(dev); | 162 | struct mlx4_priv *priv = mlx4_priv(dev); |
159 | struct mlx4_cmd_mailbox *mailbox; | 163 | struct mlx4_cmd_mailbox *mailbox; |
@@ -202,13 +206,18 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) | |||
202 | } | 206 | } |
203 | 207 | ||
204 | for (i = 0; i < members_count; ++i) | 208 | for (i = 0; i < members_count; ++i) |
205 | if (mgm->qp[i] == cpu_to_be32(qp->qpn)) { | 209 | if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) { |
206 | mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn); | 210 | mlx4_dbg(dev, "QP %06x already a member of MGM\n", qp->qpn); |
207 | err = 0; | 211 | err = 0; |
208 | goto out; | 212 | goto out; |
209 | } | 213 | } |
210 | 214 | ||
211 | mgm->qp[members_count++] = cpu_to_be32(qp->qpn); | 215 | if (block_mcast_loopback) |
216 | mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) | | ||
217 | (1 << MGM_BLCK_LB_BIT)); | ||
218 | else | ||
219 | mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK); | ||
220 | |||
212 | mgm->members_count = cpu_to_be32(members_count); | 221 | mgm->members_count = cpu_to_be32(members_count); |
213 | 222 | ||
214 | err = mlx4_WRITE_MCG(dev, index, mailbox); | 223 | err = mlx4_WRITE_MCG(dev, index, mailbox); |
@@ -283,7 +292,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) | |||
283 | 292 | ||
284 | members_count = be32_to_cpu(mgm->members_count); | 293 | members_count = be32_to_cpu(mgm->members_count); |
285 | for (loc = -1, i = 0; i < members_count; ++i) | 294 | for (loc = -1, i = 0; i < members_count; ++i) |
286 | if (mgm->qp[i] == cpu_to_be32(qp->qpn)) | 295 | if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) |
287 | loc = i; | 296 | loc = i; |
288 | 297 | ||
289 | if (loc == -1) { | 298 | if (loc == -1) { |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index a744383d16e9..81b3dd5206e0 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -398,7 +398,8 @@ int mlx4_srq_query(struct mlx4_dev *dev, struct mlx4_srq *srq, int *limit_waterm | |||
398 | int mlx4_INIT_PORT(struct mlx4_dev *dev, int port); | 398 | int mlx4_INIT_PORT(struct mlx4_dev *dev, int port); |
399 | int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); | 399 | int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); |
400 | 400 | ||
401 | int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); | 401 | int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], |
402 | int block_mcast_loopback); | ||
402 | int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); | 403 | int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); |
403 | 404 | ||
404 | int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list, | 405 | int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list, |