[ewg] RAW ETH support for Mellanox v1 [PATCH 1/1]
Aleksey Senin
alekseys at voltaire.com
Wed Jun 9 04:29:57 PDT 2010
Add RAW ETH QP support for Mellanox adapters.
Signed-off-by: Aleksey Senin <alekseys at voltaire.com>
---
drivers/infiniband/hw/mlx4/main.c | 13 +++++++++----
drivers/infiniband/hw/mlx4/qp.c | 25 +++++++++++++++++++++----
drivers/net/mlx4/mcg.c | 22 +++++++++++++---------
include/linux/mlx4/device.h | 7 +++++--
4 files changed, 48 insertions(+), 19 deletions(-)
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index c146b84..6841dc7 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -684,7 +684,9 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
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));
+ MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK),
+ (ibqp->qp_type == IB_QPT_RAW_ETH) ?
+ MLX4_PROT_EN : MLX4_PROT_IB);
if (err)
return err;
@@ -695,7 +697,9 @@ 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,
+ (ibqp->qp_type == IB_QPT_RAW_ETH) ?
+ MLX4_PROT_EN : MLX4_PROT_IB);
return err;
}
@@ -724,8 +728,9 @@ static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
struct net_device *ndev;
struct gid_entry *ge;
- err = mlx4_multicast_detach(mdev->dev,
- &mqp->mqp, gid->raw);
+ err = mlx4_multicast_detach(mdev->dev, &mqp->mqp, gid->raw,
+ (ibqp->qp_type == IB_QPT_RAW_ETH) ?
+ MLX4_PROT_EN : MLX4_PROT_IB);
if (err)
return err;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 422d367..b6b484d 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -811,6 +811,7 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
case IB_QPT_RC:
case IB_QPT_UC:
case IB_QPT_UD:
+ case IB_QPT_RAW_ETH:
{
qp = kzalloc(sizeof *qp, GFP_KERNEL);
if (!qp)
@@ -902,6 +903,7 @@ static int to_mlx4_st(enum ib_qp_type type)
case IB_QPT_RAW_ETY:
case IB_QPT_SMI:
case IB_QPT_GSI: return MLX4_QP_ST_MLX;
+ case IB_QPT_RAW_ETH: return MLX4_QP_ST_MLX;
default: return -1;
}
}
@@ -1064,8 +1066,9 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
break;
}
}
-
- if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI ||
+ if (ibqp->qp_type == IB_QPT_RAW_ETH)
+ context->mtu_msgmax = 0xff;
+ else if (ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI ||
ibqp->qp_type == IB_QPT_RAW_ETY)
context->mtu_msgmax = (IB_MTU_4096 << 5) | 11;
else if (ibqp->qp_type == IB_QPT_UD) {
@@ -1237,12 +1240,16 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
if (cur_state == IB_QPS_INIT &&
new_state == IB_QPS_RTR &&
(ibqp->qp_type == IB_QPT_GSI || ibqp->qp_type == IB_QPT_SMI ||
- ibqp->qp_type == IB_QPT_UD || ibqp->qp_type == IB_QPT_RAW_ETY)) {
+ ibqp->qp_type == IB_QPT_UD || ibqp->qp_type == IB_QPT_RAW_ETY ||
+ ibqp->qp_type == IB_QPT_RAW_ETH)) {
context->pri_path.sched_queue = (qp->port - 1) << 6;
if (is_qp0(dev, qp))
context->pri_path.sched_queue |= MLX4_IB_DEFAULT_QP0_SCHED_QUEUE;
else
context->pri_path.sched_queue |= MLX4_IB_DEFAULT_SCHED_QUEUE;
+
+ /* Default counter for non-RC QPs */
+ context->pri_path.counter_index = 0xff;
}
if (cur_state == IB_QPS_RTS && new_state == IB_QPS_SQD &&
@@ -1356,7 +1363,7 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
goto out;
}
- if ((attr_mask & IB_QP_PORT) &&
+ if ((attr_mask & IB_QP_PORT) && (ibqp->qp_type != IB_QPT_RAW_ETH) &&
(attr->port_num == 0 || attr->port_num > dev->num_ports)) {
mlx4_ib_dbg("qpn 0x%x: invalid port number (%d) specified "
"for transition %d to %d. qp_type %d",
@@ -1365,6 +1372,16 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
goto out;
}
+ if ((attr_mask & IB_QP_PORT) && (ibqp->qp_type == IB_QPT_RAW_ETH) &&
+ (rdma_port_link_layer(&dev->ib_dev, attr->port_num)
+ != IB_LINK_LAYER_ETHERNET)) {
+ mlx4_ib_dbg("qpn 0x%x: invalid port (%d) specified (not RDMAoE)"
+ "for transition %d to %d. qp_type %d",
+ ibqp->qp_num, attr->port_num, cur_state,
+ new_state, ibqp->qp_type);
+ goto out;
+ }
+
if (attr_mask & IB_QP_PKEY_INDEX) {
int p = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
if (attr->pkey_index >= dev->dev->caps.pkey_table_len[p]) {
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index 61c1e40..10a3eb5 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -36,6 +36,7 @@
#include <linux/slab.h>
#include <linux/mlx4/cmd.h>
+#include <linux/mlx4/driver.h>
#include "mlx4.h"
@@ -97,7 +98,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_prot prot,
+ struct mlx4_cmd_mailbox *mgm_mailbox,
u16 *hash, int *prev, int *index)
{
struct mlx4_cmd_mailbox *mailbox;
@@ -146,8 +148,9 @@ static int find_mgm(struct mlx4_dev *dev,
return err;
}
- if (!memcmp(mgm->gid, gid, 16))
- return err;
+ if (!memcmp(mgm->gid, gid, 16) &&
+ (prot == be32_to_cpu(mgm->members_count) >> 30))
+ return err;
*prev = *index;
*index = be32_to_cpu(mgm->next_gid_index) >> 6;
@@ -158,7 +161,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_prot prot)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_cmd_mailbox *mailbox;
@@ -177,7 +180,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, prot, mailbox, &hash, &prev, &index);
if (err)
goto out;
@@ -216,7 +219,7 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
mgm->qp[members_count++] = cpu_to_be32((qp->qpn & MGM_QPN_MASK) |
(!!mlx4_blck_lb << MGM_BLCK_LB_BIT));
- mgm->members_count = cpu_to_be32(members_count);
+ mgm->members_count = cpu_to_be32(members_count | ((u32) prot << 30));
err = mlx4_WRITE_MCG(dev, index, mailbox);
if (err)
@@ -251,7 +254,8 @@ out:
}
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_prot prot)
{
struct mlx4_priv *priv = mlx4_priv(dev);
struct mlx4_cmd_mailbox *mailbox;
@@ -269,7 +273,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, prot, mailbox, &hash, &prev, &index);
if (err)
goto out;
@@ -300,7 +304,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) prot << 30));
mgm->qp[loc] = mgm->qp[i - 1];
mgm->qp[i - 1] = 0;
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 782a9b5..9ca1326 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -39,6 +39,8 @@
#include <asm/atomic.h>
+#include <linux/mlx4/driver.h>
+
enum {
MLX4_FLAG_MSI_X = 1 << 0,
MLX4_FLAG_OLD_PORT_CMDS = 1 << 1,
@@ -561,8 +563,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_prot prot);
+int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16],
+ enum mlx4_prot prot);
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);
--
1.6.5.2
More information about the ewg
mailing list