Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 242638
b: refs/heads/master
c: 0345584
h: refs/heads/master
v: v3
  • Loading branch information
Yevgeny Petrilin authored and David S. Miller committed Mar 23, 2011
1 parent a70c838 commit 7345589
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 44 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 725c89997e03d71b09ea3c17c997da0712b9d835
refs/heads/master: 0345584e0b8be3735a950d17c7e463db20c6ce27
10 changes: 5 additions & 5 deletions trunk/drivers/infiniband/hw/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)

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

Expand All @@ -636,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_PROTOCOL_IB);
mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw, MLX4_PROT_IB_IPV6);
return err;
}

Expand Down Expand Up @@ -666,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, MLX4_PROTOCOL_IB);
&mqp->mqp, gid->raw, MLX4_PROT_IB_IPV6);
if (err)
return err;

Expand Down Expand Up @@ -953,7 +953,7 @@ static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long event
mlx4_foreach_ib_transport_port(port, ibdev->dev) {
oldnd = iboe->netdevs[port - 1];
iboe->netdevs[port - 1] =
mlx4_get_protocol_dev(ibdev->dev, MLX4_PROTOCOL_EN, port);
mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port);
if (oldnd != iboe->netdevs[port - 1]) {
if (iboe->netdevs[port - 1])
netdev_added(ibdev, port);
Expand Down Expand Up @@ -1206,7 +1206,7 @@ static struct mlx4_interface mlx4_ib_interface = {
.add = mlx4_ib_add,
.remove = mlx4_ib_remove,
.event = mlx4_ib_event,
.protocol = MLX4_PROTOCOL_IB
.protocol = MLX4_PROT_IB_IPV6
};

static int __init mlx4_ib_init(void)
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/mlx4/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ static struct mlx4_interface mlx4_en_interface = {
.remove = mlx4_en_remove,
.event = mlx4_en_event,
.get_dev = mlx4_en_get_netdev,
.protocol = MLX4_PROTOCOL_EN,
.protocol = MLX4_PROT_ETH,
};

static int __init mlx4_en_init(void)
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/mlx4/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev_cap->stat_rate_support = stat_rate;
MLX4_GET(field, outbox, QUERY_DEV_CAP_UDP_RSS_OFFSET);
dev_cap->udp_rss = field & 0x1;
dev_cap->vep_uc_steering = field & 0x2;
dev_cap->vep_mc_steering = field & 0x4;
MLX4_GET(field, outbox, QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET);
dev_cap->loopback_support = field & 0x1;
dev_cap->wol = field & 0x40;
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/mlx4/fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ struct mlx4_dev_cap {
u16 stat_rate_support;
int udp_rss;
int loopback_support;
int vep_uc_steering;
int vep_mc_steering;
int wol;
u32 flags;
int reserved_uars;
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
dev->caps.stat_rate_support = dev_cap->stat_rate_support;
dev->caps.udp_rss = dev_cap->udp_rss;
dev->caps.loopback_support = dev_cap->loopback_support;
dev->caps.vep_uc_steering = dev_cap->vep_uc_steering;
dev->caps.vep_mc_steering = dev_cap->vep_mc_steering;
dev->caps.wol = dev_cap->wol;
dev->caps.max_gso_sz = dev_cap->max_gso_sz;

Expand Down
113 changes: 78 additions & 35 deletions trunk/drivers/net/mlx4/mcg.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
*/

#include <linux/string.h>
#include <linux/etherdevice.h>

#include <linux/mlx4/cmd.h>

Expand All @@ -50,28 +51,28 @@ struct mlx4_mgm {

static const u8 zero_gid[16]; /* automatically initialized to 0 */

static int mlx4_READ_MCG(struct mlx4_dev *dev, int index,
struct mlx4_cmd_mailbox *mailbox)
static int mlx4_READ_ENTRY(struct mlx4_dev *dev, int index,
struct mlx4_cmd_mailbox *mailbox)
{
return mlx4_cmd_box(dev, 0, mailbox->dma, index, 0, MLX4_CMD_READ_MCG,
MLX4_CMD_TIME_CLASS_A);
}

static int mlx4_WRITE_MCG(struct mlx4_dev *dev, int index,
struct mlx4_cmd_mailbox *mailbox)
static int mlx4_WRITE_ENTRY(struct mlx4_dev *dev, int index,
struct mlx4_cmd_mailbox *mailbox)
{
return mlx4_cmd(dev, mailbox->dma, index, 0, MLX4_CMD_WRITE_MCG,
MLX4_CMD_TIME_CLASS_A);
}

static int mlx4_MGID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
u16 *hash)
static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
u16 *hash, u8 op_mod)
{
u64 imm;
int err;

err = mlx4_cmd_imm(dev, mailbox->dma, &imm, 0, 0, MLX4_CMD_MGID_HASH,
MLX4_CMD_TIME_CLASS_A);
err = mlx4_cmd_imm(dev, mailbox->dma, &imm, 0, op_mod,
MLX4_CMD_MGID_HASH, MLX4_CMD_TIME_CLASS_A);

if (!err)
*hash = imm;
Expand All @@ -94,15 +95,17 @@ static int mlx4_MGID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox
* If no AMGM exists for given gid, *index = -1, *prev = index of last
* entry in hash chain and *mgm holds end of hash chain.
*/
static int find_mgm(struct mlx4_dev *dev,
u8 *gid, enum mlx4_protocol protocol,
struct mlx4_cmd_mailbox *mgm_mailbox,
u16 *hash, int *prev, int *index)
static int find_entry(struct mlx4_dev *dev, u8 port,
u8 *gid, enum mlx4_protocol prot,
enum mlx4_steer_type steer,
struct mlx4_cmd_mailbox *mgm_mailbox,
u16 *hash, int *prev, int *index)
{
struct mlx4_cmd_mailbox *mailbox;
struct mlx4_mgm *mgm = mgm_mailbox->buf;
u8 *mgid;
int err;
u8 op_mod = (prot == MLX4_PROT_ETH) ? !!(dev->caps.vep_mc_steering) : 0;

mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
Expand All @@ -111,7 +114,7 @@ static int find_mgm(struct mlx4_dev *dev,

memcpy(mgid, gid, 16);

err = mlx4_MGID_HASH(dev, mailbox, hash);
err = mlx4_GID_HASH(dev, mailbox, hash, op_mod);
mlx4_free_cmd_mailbox(dev, mailbox);
if (err)
return err;
Expand All @@ -123,11 +126,11 @@ static int find_mgm(struct mlx4_dev *dev,
*prev = -1;

do {
err = mlx4_READ_MCG(dev, *index, mgm_mailbox);
err = mlx4_READ_ENTRY(dev, *index, mgm_mailbox);
if (err)
return err;

if (!memcmp(mgm->gid, zero_gid, 16)) {
if (!(be32_to_cpu(mgm->members_count) & 0xffffff)) {
if (*index != *hash) {
mlx4_err(dev, "Found zero MGID in AMGM.\n");
err = -EINVAL;
Expand All @@ -136,7 +139,7 @@ static int find_mgm(struct mlx4_dev *dev,
}

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

*prev = *index;
Expand All @@ -147,8 +150,9 @@ static int find_mgm(struct mlx4_dev *dev,
return err;
}

int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
int block_mcast_loopback, enum mlx4_protocol protocol)
int mlx4_qp_attach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
int block_mcast_loopback, enum mlx4_protocol prot,
enum mlx4_steer_type steer)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_cmd_mailbox *mailbox;
Expand All @@ -159,20 +163,21 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
int link = 0;
int i;
int err;
u8 port = gid[5];

mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
return PTR_ERR(mailbox);
mgm = mailbox->buf;

mutex_lock(&priv->mcg_table.mutex);

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

if (index != -1) {
if (!memcmp(mgm->gid, zero_gid, 16))
if (!(be32_to_cpu(mgm->members_count) & 0xffffff))
memcpy(mgm->gid, gid, 16);
} else {
link = 1;
Expand Down Expand Up @@ -209,22 +214,22 @@ 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 | (u32) protocol << 30);
mgm->members_count = cpu_to_be32(members_count | (u32) prot << 30);

err = mlx4_WRITE_MCG(dev, index, mailbox);
err = mlx4_WRITE_ENTRY(dev, index, mailbox);
if (err)
goto out;

if (!link)
goto out;

err = mlx4_READ_MCG(dev, prev, mailbox);
err = mlx4_READ_ENTRY(dev, prev, mailbox);
if (err)
goto out;

mgm->next_gid_index = cpu_to_be32(index << 6);

err = mlx4_WRITE_MCG(dev, prev, mailbox);
err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
if (err)
goto out;

Expand All @@ -242,10 +247,9 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
mlx4_free_cmd_mailbox(dev, mailbox);
return err;
}
EXPORT_SYMBOL_GPL(mlx4_multicast_attach);

int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
enum mlx4_protocol protocol)
int mlx4_qp_detach_common(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
enum mlx4_protocol prot, enum mlx4_steer_type steer)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_cmd_mailbox *mailbox;
Expand All @@ -255,6 +259,7 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
int prev, index;
int i, loc;
int err;
u8 port = gid[5];

mailbox = mlx4_alloc_cmd_mailbox(dev);
if (IS_ERR(mailbox))
Expand All @@ -263,7 +268,8 @@ 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, protocol, mailbox, &hash, &prev, &index);
err = find_entry(dev, port, gid, prot, steer,
mailbox, &hash, &prev, &index);
if (err)
goto out;

Expand All @@ -285,26 +291,26 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
}


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

if (i != 1) {
err = mlx4_WRITE_MCG(dev, index, mailbox);
err = mlx4_WRITE_ENTRY(dev, index, mailbox);
goto out;
}

if (prev == -1) {
/* Remove entry from MGM */
int amgm_index = be32_to_cpu(mgm->next_gid_index) >> 6;
if (amgm_index) {
err = mlx4_READ_MCG(dev, amgm_index, mailbox);
err = mlx4_READ_ENTRY(dev, amgm_index, mailbox);
if (err)
goto out;
} else
memset(mgm->gid, 0, 16);

err = mlx4_WRITE_MCG(dev, index, mailbox);
err = mlx4_WRITE_ENTRY(dev, index, mailbox);
if (err)
goto out;

Expand All @@ -319,13 +325,13 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
} else {
/* Remove entry from AMGM */
int cur_next_index = be32_to_cpu(mgm->next_gid_index) >> 6;
err = mlx4_READ_MCG(dev, prev, mailbox);
err = mlx4_READ_ENTRY(dev, prev, mailbox);
if (err)
goto out;

mgm->next_gid_index = cpu_to_be32(cur_next_index << 6);

err = mlx4_WRITE_MCG(dev, prev, mailbox);
err = mlx4_WRITE_ENTRY(dev, prev, mailbox);
if (err)
goto out;

Expand All @@ -343,6 +349,43 @@ int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
mlx4_free_cmd_mailbox(dev, mailbox);
return err;
}


int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
int block_mcast_loopback, enum mlx4_protocol prot)
{
enum mlx4_steer_type steer;

steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER;

if (prot == MLX4_PROT_ETH && !dev->caps.vep_mc_steering)
return 0;

if (prot == MLX4_PROT_ETH)
gid[7] |= (steer << 1);

return mlx4_qp_attach_common(dev, qp, gid,
block_mcast_loopback, prot,
steer);
}
EXPORT_SYMBOL_GPL(mlx4_multicast_attach);

int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
enum mlx4_protocol prot)
{
enum mlx4_steer_type steer;

steer = (is_valid_ether_addr(&gid[10])) ? MLX4_UC_STEER : MLX4_MC_STEER;

if (prot == MLX4_PROT_ETH && !dev->caps.vep_mc_steering)
return 0;

if (prot == MLX4_PROT_ETH) {
gid[7] |= (steer << 1);
}

return mlx4_qp_detach_common(dev, qp, gid, prot, steer);
}
EXPORT_SYMBOL_GPL(mlx4_multicast_detach);

int mlx4_init_mcg_table(struct mlx4_dev *dev)
Expand Down
Loading

0 comments on commit 7345589

Please sign in to comment.