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>

authored by Aleksey Senin and committed by Roland Dreier da995a8a 4979d18f

+27 -21
+5 -4
drivers/infiniband/hw/mlx4/main.c
··· 623 623 struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); 624 624 struct mlx4_ib_qp *mqp = to_mqp(ibqp); 625 625 626 - err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, !!(mqp->flags & 627 - MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK)); 626 + err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, 627 + !!(mqp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK), 628 + MLX4_PROTOCOL_IB); 628 629 if (err) 629 630 return err; 630 631 ··· 636 635 return 0; 637 636 638 637 err_add: 639 - mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw); 638 + mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, MLX4_PROTOCOL_IB); 640 639 return err; 641 640 } 642 641 ··· 666 665 struct mlx4_ib_gid_entry *ge; 667 666 668 667 err = mlx4_multicast_detach(mdev->dev, 669 - &mqp->mqp, gid->raw); 668 + &mqp->mqp, gid->raw, MLX4_PROTOCOL_IB); 670 669 if (err) 671 670 return err; 672 671
+13 -10
drivers/net/mlx4/mcg.c
··· 95 95 * entry in hash chain and *mgm holds end of hash chain. 96 96 */ 97 97 static 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 100 u16 *hash, int *prev, int *index) 100 101 { 101 102 struct mlx4_cmd_mailbox *mailbox; ··· 135 134 return err; 136 135 } 137 136 138 - if (!memcmp(mgm->gid, gid, 16)) 137 + if (!memcmp(mgm->gid, gid, 16) && 138 + be32_to_cpu(mgm->members_count) >> 30 == protocol) 139 139 return err; 140 140 141 141 *prev = *index; ··· 148 146 } 149 147 150 148 int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 151 - int block_mcast_loopback) 149 + int block_mcast_loopback, enum mlx4_protocol protocol) 152 150 { 153 151 struct mlx4_priv *priv = mlx4_priv(dev); 154 152 struct mlx4_cmd_mailbox *mailbox; ··· 167 165 168 166 mutex_lock(&priv->mcg_table.mutex); 169 167 170 - err = find_mgm(dev, gid, mailbox, &hash, &prev, &index); 168 + err = find_mgm(dev, gid, protocol, mailbox, &hash, &prev, &index); 171 169 if (err) 172 170 goto out; 173 171 ··· 189 187 memcpy(mgm->gid, gid, 16); 190 188 } 191 189 192 - members_count = be32_to_cpu(mgm->members_count); 190 + members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 193 191 if (members_count == MLX4_QP_PER_MGM) { 194 192 mlx4_err(dev, "MGM at index %x is full.\n", index); 195 193 err = -ENOMEM; ··· 209 207 else 210 208 mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK); 211 209 212 - mgm->members_count = cpu_to_be32(members_count); 210 + mgm->members_count = cpu_to_be32(members_count | (u32) protocol << 30); 213 211 214 212 err = mlx4_WRITE_MCG(dev, index, mailbox); 215 213 if (err) ··· 244 242 } 245 243 EXPORT_SYMBOL_GPL(mlx4_multicast_attach); 246 244 247 - int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]) 245 + int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 246 + enum mlx4_protocol protocol) 248 247 { 249 248 struct mlx4_priv *priv = mlx4_priv(dev); 250 249 struct mlx4_cmd_mailbox *mailbox; ··· 263 260 264 261 mutex_lock(&priv->mcg_table.mutex); 265 262 266 - err = find_mgm(dev, gid, mailbox, &hash, &prev, &index); 263 + err = find_mgm(dev, gid, protocol, mailbox, &hash, &prev, &index); 267 264 if (err) 268 265 goto out; 269 266 ··· 273 270 goto out; 274 271 } 275 272 276 - members_count = be32_to_cpu(mgm->members_count); 273 + members_count = be32_to_cpu(mgm->members_count) & 0xffffff; 277 274 for (loc = -1, i = 0; i < members_count; ++i) 278 275 if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn) 279 276 loc = i; ··· 285 282 } 286 283 287 284 288 - mgm->members_count = cpu_to_be32(--members_count); 285 + mgm->members_count = cpu_to_be32(--members_count | (u32) protocol << 30); 289 286 mgm->qp[loc] = mgm->qp[i - 1]; 290 287 mgm->qp[i - 1] = 0; 291 288
+8 -2
include/linux/mlx4/device.h
··· 144 144 MLX4_STAT_RATE_OFFSET = 5 145 145 }; 146 146 147 + enum mlx4_protocol { 148 + MLX4_PROTOCOL_IB, 149 + MLX4_PROTOCOL_EN, 150 + }; 151 + 147 152 enum { 148 153 MLX4_MTT_FLAG_PRESENT = 1 149 154 }; ··· 505 500 int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port); 506 501 507 502 int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 508 - int block_mcast_loopback); 509 - int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); 503 + int block_mcast_loopback, enum mlx4_protocol protocol); 504 + int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], 505 + enum mlx4_protocol protocol); 510 506 511 507 int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index); 512 508 void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index);
+1 -5
include/linux/mlx4/driver.h
··· 34 34 #define MLX4_DRIVER_H 35 35 36 36 #include <linux/device.h> 37 + #include <linux/mlx4/device.h> 37 38 38 39 struct mlx4_dev; 39 40 ··· 43 42 MLX4_DEV_EVENT_PORT_UP, 44 43 MLX4_DEV_EVENT_PORT_DOWN, 45 44 MLX4_DEV_EVENT_PORT_REINIT, 46 - }; 47 - 48 - enum mlx4_protocol { 49 - MLX4_PROTOCOL_IB, 50 - MLX4_PROTOCOL_EN, 51 45 }; 52 46 53 47 struct mlx4_interface {