aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Senin <alex@senin.name>2010-12-02 06:44:49 -0500
committerRoland Dreier <rolandd@cisco.com>2011-01-12 17:49:17 -0500
commitda995a8aee044bc5d0847e19e351cd48a2cb8bcc (patch)
tree000cb11c5e49e1bc91a2212ed5a2299f279c990b
parent4979d18fe105297f8f065743f31f8f735da8df2d (diff)
IB/mlx4: Handle protocol field in multicast table
The newest device firmware stores IB vs. Ethernet protocol in two bits in members_count field of multicast group table (0: Infiniband, 1: Ethernet). When changing the QP members count for a multicast group, it important not to reset this information. When calling multicast attach first time, the protocol type should be specified. In this patch we always set it IB, but in the future we will handle Ethernet too. When looking for a QP, the protocol type shoud be checked too. Signed-off-by: Aleksey Senin <alekseys@voltaire.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/mlx4/main.c9
-rw-r--r--drivers/net/mlx4/mcg.c23
-rw-r--r--include/linux/mlx4/device.h10
-rw-r--r--include/linux/mlx4/driver.h6
4 files changed, 27 insertions, 21 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index d68d849ab866..c7a6213c6996 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -623,8 +623,9 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
623 struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); 623 struct mlx4_ib_dev *mdev = to_mdev(ibqp->device);
624 struct mlx4_ib_qp *mqp = to_mqp(ibqp); 624 struct mlx4_ib_qp *mqp = to_mqp(ibqp);
625 625
626 err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, !!(mqp->flags & 626 err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw,
627 MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK)); 627 !!(mqp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK),
628 MLX4_PROTOCOL_IB);
628 if (err) 629 if (err)
629 return err; 630 return err;
630 631
@@ -635,7 +636,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
635 return 0; 636 return 0;
636 637
637err_add: 638err_add:
638 mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw); 639 mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, MLX4_PROTOCOL_IB);
639 return err; 640 return err;
640} 641}
641 642
@@ -665,7 +666,7 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
665 struct mlx4_ib_gid_entry *ge; 666 struct mlx4_ib_gid_entry *ge;
666 667
667 err = mlx4_multicast_detach(mdev->dev, 668 err = mlx4_multicast_detach(mdev->dev,
668 &mqp->mqp, gid->raw); 669 &mqp->mqp, gid->raw, MLX4_PROTOCOL_IB);
669 if (err) 670 if (err)
670 return err; 671 return err;
671 672
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index c4f88b7ef7b6..79cf42db2ea9 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -95,7 +95,8 @@ static int mlx4_MGID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox
95 * entry in hash chain and *mgm holds end of hash chain. 95 * entry in hash chain and *mgm holds end of hash chain.
96 */ 96 */
97static int find_mgm(struct mlx4_dev *dev, 97static int find_mgm(struct mlx4_dev *dev,
98 u8 *gid, struct mlx4_cmd_mailbox *mgm_mailbox, 98 u8 *gid, enum mlx4_protocol protocol,
99 struct mlx4_cmd_mailbox *mgm_mailbox,
99 u16 *hash, int *prev, int *index) 100 u16 *hash, int *prev, int *index)
100{ 101{
101 struct mlx4_cmd_mailbox *mailbox; 102 struct mlx4_cmd_mailbox *mailbox;
@@ -134,7 +135,8 @@ static int find_mgm(struct mlx4_dev *dev,
134 return err; 135 return err;
135 } 136 }
136 137
137 if (!memcmp(mgm->gid, gid, 16)) 138 if (!memcmp(mgm->gid, gid, 16) &&
139 be32_to_cpu(mgm->members_count) >> 30 == protocol)
138 return err; 140 return err;
139 141
140 *prev = *index; 142 *prev = *index;
@@ -146,7 +148,7 @@ static int find_mgm(struct mlx4_dev *dev,
146} 148}
147 149
148int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 150int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
149 int block_mcast_loopback) 151 int block_mcast_loopback, enum mlx4_protocol protocol)
150{ 152{
151 struct mlx4_priv *priv = mlx4_priv(dev); 153 struct mlx4_priv *priv = mlx4_priv(dev);
152 struct mlx4_cmd_mailbox *mailbox; 154 struct mlx4_cmd_mailbox *mailbox;
@@ -165,7 +167,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
165 167
166 mutex_lock(&priv->mcg_table.mutex); 168 mutex_lock(&priv->mcg_table.mutex);
167 169
168 err = find_mgm(dev, gid, mailbox, &hash, &prev, &index); 170 err = find_mgm(dev, gid, protocol, mailbox, &hash, &prev, &index);
169 if (err) 171 if (err)
170 goto out; 172 goto out;
171 173
@@ -187,7 +189,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
187 memcpy(mgm->gid, gid, 16); 189 memcpy(mgm->gid, gid, 16);
188 } 190 }
189 191
190 members_count = be32_to_cpu(mgm->members_count); 192 members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
191 if (members_count == MLX4_QP_PER_MGM) { 193 if (members_count == MLX4_QP_PER_MGM) {
192 mlx4_err(dev, "MGM at index %x is full.\n", index); 194 mlx4_err(dev, "MGM at index %x is full.\n", index);
193 err = -ENOMEM; 195 err = -ENOMEM;
@@ -207,7 +209,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
207 else 209 else
208 mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK); 210 mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK);
209 211
210 mgm->members_count = cpu_to_be32(members_count); 212 mgm->members_count = cpu_to_be32(members_count | (u32) protocol << 30);
211 213
212 err = mlx4_WRITE_MCG(dev, index, mailbox); 214 err = mlx4_WRITE_MCG(dev, index, mailbox);
213 if (err) 215 if (err)
@@ -242,7 +244,8 @@ out:
242} 244}
243EXPORT_SYMBOL_GPL(mlx4_multicast_attach); 245EXPORT_SYMBOL_GPL(mlx4_multicast_attach);
244 246
245int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) 247int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
248 enum mlx4_protocol protocol)
246{ 249{
247 struct mlx4_priv *priv = mlx4_priv(dev); 250 struct mlx4_priv *priv = mlx4_priv(dev);
248 struct mlx4_cmd_mailbox *mailbox; 251 struct mlx4_cmd_mailbox *mailbox;
@@ -260,7 +263,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
260 263
261 mutex_lock(&priv->mcg_table.mutex); 264 mutex_lock(&priv->mcg_table.mutex);
262 265
263 err = find_mgm(dev, gid, mailbox, &hash, &prev, &index); 266 err = find_mgm(dev, gid, protocol, mailbox, &hash, &prev, &index);
264 if (err) 267 if (err)
265 goto out; 268 goto out;
266 269
@@ -270,7 +273,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
270 goto out; 273 goto out;
271 } 274 }
272 275
273 members_count = be32_to_cpu(mgm->members_count); 276 members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
274 for (loc = -1, i = 0; i < members_count; ++i) 277 for (loc = -1, i = 0; i < members_count; ++i)
275 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) 278 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn)
276 loc = i; 279 loc = i;
@@ -282,7 +285,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
282 } 285 }
283 286
284 287
285 mgm->members_count = cpu_to_be32(--members_count); 288 mgm->members_count = cpu_to_be32(--members_count | (u32) protocol << 30);
286 mgm->qp[loc] = mgm->qp[i - 1]; 289 mgm->qp[loc] = mgm->qp[i - 1];
287 mgm->qp[i - 1] = 0; 290 mgm->qp[i - 1] = 0;
288 291
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index a7b15bc7648e..049214642036 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -144,6 +144,11 @@ enum {
144 MLX4_STAT_RATE_OFFSET = 5 144 MLX4_STAT_RATE_OFFSET = 5
145}; 145};
146 146
147enum mlx4_protocol {
148 MLX4_PROTOCOL_IB,
149 MLX4_PROTOCOL_EN,
150};
151
147enum { 152enum {
148 MLX4_MTT_FLAG_PRESENT = 1 153 MLX4_MTT_FLAG_PRESENT = 1
149}; 154};
@@ -500,8 +505,9 @@ int mlx4_INIT_PORT(struct mlx4_dev *dev, int port);
500int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); 505int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port);
501 506
502int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 507int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
503 int block_mcast_loopback); 508 int block_mcast_loopback, enum mlx4_protocol protocol);
504int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); 509int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
510 enum mlx4_protocol protocol);
505 511
506int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index); 512int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index);
507void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index); 513void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index);
diff --git a/include/linux/mlx4/driver.h b/include/linux/mlx4/driver.h
index f407cd4bfb34..e1eebf78caba 100644
--- a/include/linux/mlx4/driver.h
+++ b/include/linux/mlx4/driver.h
@@ -34,6 +34,7 @@
34#define MLX4_DRIVER_H 34#define MLX4_DRIVER_H
35 35
36#include <linux/device.h> 36#include <linux/device.h>
37#include <linux/mlx4/device.h>
37 38
38struct mlx4_dev; 39struct mlx4_dev;
39 40
@@ -44,11 +45,6 @@ enum mlx4_dev_event {
44 MLX4_DEV_EVENT_PORT_REINIT, 45 MLX4_DEV_EVENT_PORT_REINIT,
45}; 46};
46 47
47enum mlx4_protocol {
48 MLX4_PROTOCOL_IB,
49 MLX4_PROTOCOL_EN,
50};
51
52struct mlx4_interface { 48struct mlx4_interface {
53 void * (*add) (struct mlx4_dev *dev); 49 void * (*add) (struct mlx4_dev *dev);
54 void (*remove)(struct mlx4_dev *dev, void *context); 50 void (*remove)(struct mlx4_dev *dev, void *context);