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