aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/mlx4/main.c7
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h3
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c21
-rw-r--r--drivers/net/mlx4/mcg.c17
-rw-r--r--include/linux/mlx4/device.h3
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)
437static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) 438static 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
443static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) 446static 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
103enum mlx4_ib_qp_flags { 103enum 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
107struct mlx4_ib_qp { 108struct 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
1847out: 1862out:
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
41struct mlx4_mgm { 44struct 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
156int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) 159int 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
398int mlx4_INIT_PORT(struct mlx4_dev *dev, int port); 398int mlx4_INIT_PORT(struct mlx4_dev *dev, int port);
399int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); 399int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port);
400 400
401int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); 401int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
402 int block_mcast_loopback);
402int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); 403int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]);
403 404
404int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list, 405int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list,