Skip to content

Commit

Permalink
IB/mlx4: Handle protocol field in multicast table
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Aleksey Senin authored and Roland Dreier committed Jan 12, 2011
1 parent 4979d18 commit da995a8
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 21 deletions.
9 changes: 5 additions & 4 deletions drivers/infiniband/hw/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,9 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
struct mlx4_ib_dev *mdev = to_mdev(ibqp->device);
struct mlx4_ib_qp *mqp = to_mqp(ibqp);

err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw, !!(mqp->flags &
MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK));
err = mlx4_multicast_attach(mdev->dev, &mqp->mqp, gid->raw,
!!(mqp->flags & MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK),
MLX4_PROTOCOL_IB);
if (err)
return err;

Expand All @@ -635,7 +636,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
return 0;

err_add:
mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw);
mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, MLX4_PROTOCOL_IB);
return err;
}

Expand Down Expand Up @@ -665,7 +666,7 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
struct mlx4_ib_gid_entry *ge;

err = mlx4_multicast_detach(mdev->dev,
&mqp->mqp, gid->raw);
&mqp->mqp, gid->raw, MLX4_PROTOCOL_IB);
if (err)
return err;

Expand Down
23 changes: 13 additions & 10 deletions drivers/net/mlx4/mcg.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ static int mlx4_MGID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox
* entry in hash chain and *mgm holds end of hash chain.
*/
static int find_mgm(struct mlx4_dev *dev,
u8 *gid, struct mlx4_cmd_mailbox *mgm_mailbox,
u8 *gid, enum mlx4_protocol protocol,
struct mlx4_cmd_mailbox *mgm_mailbox,
u16 *hash, int *prev, int *index)
{
struct mlx4_cmd_mailbox *mailbox;
Expand Down Expand Up @@ -134,7 +135,8 @@ static int find_mgm(struct mlx4_dev *dev,
return err;
}

if (!memcmp(mgm->gid, gid, 16))
if (!memcmp(mgm->gid, gid, 16) &&
be32_to_cpu(mgm->members_count) >> 30 == protocol)
return err;

*prev = *index;
Expand All @@ -146,7 +148,7 @@ static int find_mgm(struct mlx4_dev *dev,
}

int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
int block_mcast_loopback)
int block_mcast_loopback, enum mlx4_protocol protocol)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_cmd_mailbox *mailbox;
Expand All @@ -165,7 +167,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],

mutex_lock(&priv->mcg_table.mutex);

err = find_mgm(dev, gid, mailbox, &hash, &prev, &index);
err = find_mgm(dev, gid, protocol, mailbox, &hash, &prev, &index);
if (err)
goto out;

Expand All @@ -187,7 +189,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
memcpy(mgm->gid, gid, 16);
}

members_count = be32_to_cpu(mgm->members_count);
members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
if (members_count == MLX4_QP_PER_MGM) {
mlx4_err(dev, "MGM at index %x is full.\n", index);
err = -ENOMEM;
Expand All @@ -207,7 +209,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
else
mgm->qp[members_count++] = cpu_to_be32(qp->qpn & MGM_QPN_MASK);

mgm->members_count = cpu_to_be32(members_count);
mgm->members_count = cpu_to_be32(members_count | (u32) protocol << 30);

err = mlx4_WRITE_MCG(dev, index, mailbox);
if (err)
Expand Down Expand Up @@ -242,7 +244,8 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
}
EXPORT_SYMBOL_GPL(mlx4_multicast_attach);

int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
enum mlx4_protocol protocol)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_cmd_mailbox *mailbox;
Expand All @@ -260,7 +263,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])

mutex_lock(&priv->mcg_table.mutex);

err = find_mgm(dev, gid, mailbox, &hash, &prev, &index);
err = find_mgm(dev, gid, protocol, mailbox, &hash, &prev, &index);
if (err)
goto out;

Expand All @@ -270,7 +273,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
goto out;
}

members_count = be32_to_cpu(mgm->members_count);
members_count = be32_to_cpu(mgm->members_count) & 0xffffff;
for (loc = -1, i = 0; i < members_count; ++i)
if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qp->qpn)
loc = i;
Expand All @@ -282,7 +285,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16])
}


mgm->members_count = cpu_to_be32(--members_count);
mgm->members_count = cpu_to_be32(--members_count | (u32) protocol << 30);
mgm->qp[loc] = mgm->qp[i - 1];
mgm->qp[i - 1] = 0;

Expand Down
10 changes: 8 additions & 2 deletions include/linux/mlx4/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ enum {
MLX4_STAT_RATE_OFFSET = 5
};

enum mlx4_protocol {
MLX4_PROTOCOL_IB,
MLX4_PROTOCOL_EN,
};

enum {
MLX4_MTT_FLAG_PRESENT = 1
};
Expand Down Expand Up @@ -500,8 +505,9 @@ int mlx4_INIT_PORT(struct mlx4_dev *dev, int port);
int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port);

int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
int block_mcast_loopback);
int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]);
int block_mcast_loopback, enum mlx4_protocol protocol);
int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
enum mlx4_protocol protocol);

int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index);
void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index);
Expand Down
6 changes: 1 addition & 5 deletions include/linux/mlx4/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#define MLX4_DRIVER_H

#include <linux/device.h>
#include <linux/mlx4/device.h>

struct mlx4_dev;

Expand All @@ -44,11 +45,6 @@ enum mlx4_dev_event {
MLX4_DEV_EVENT_PORT_REINIT,
};

enum mlx4_protocol {
MLX4_PROTOCOL_IB,
MLX4_PROTOCOL_EN,
};

struct mlx4_interface {
void * (*add) (struct mlx4_dev *dev);
void (*remove)(struct mlx4_dev *dev, void *context);
Expand Down

0 comments on commit da995a8

Please sign in to comment.