Merge branch 'ip-roce' into for-next
Conflicts: drivers/infiniband/hw/mlx4/main.c
This commit is contained in:
@@ -90,6 +90,21 @@ enum {
|
||||
MLX4_RAW_QP_MSGMAX = 31,
|
||||
};
|
||||
|
||||
#ifndef ETH_ALEN
|
||||
#define ETH_ALEN 6
|
||||
#endif
|
||||
static inline u64 mlx4_mac_to_u64(u8 *addr)
|
||||
{
|
||||
u64 mac = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
mac <<= 8;
|
||||
mac |= addr[i];
|
||||
}
|
||||
return mac;
|
||||
}
|
||||
|
||||
static const __be32 mlx4_ib_opcode[] = {
|
||||
[IB_WR_SEND] = cpu_to_be32(MLX4_OPCODE_SEND),
|
||||
[IB_WR_LSO] = cpu_to_be32(MLX4_OPCODE_LSO),
|
||||
@@ -1171,16 +1186,15 @@ static void mlx4_set_sched(struct mlx4_qp_path *path, u8 port)
|
||||
path->sched_queue = (path->sched_queue & 0xbf) | ((port - 1) << 6);
|
||||
}
|
||||
|
||||
static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
|
||||
struct mlx4_qp_path *path, u8 port)
|
||||
static int _mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
|
||||
u64 smac, u16 vlan_tag, struct mlx4_qp_path *path,
|
||||
u8 port)
|
||||
{
|
||||
int err;
|
||||
int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port) ==
|
||||
IB_LINK_LAYER_ETHERNET;
|
||||
u8 mac[6];
|
||||
int is_mcast;
|
||||
u16 vlan_tag;
|
||||
int vidx;
|
||||
int smac_index;
|
||||
|
||||
|
||||
path->grh_mylmc = ah->src_path_bits & 0x7f;
|
||||
path->rlid = cpu_to_be16(ah->dlid);
|
||||
@@ -1215,22 +1229,27 @@ static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
|
||||
if (!(ah->ah_flags & IB_AH_GRH))
|
||||
return -1;
|
||||
|
||||
err = mlx4_ib_resolve_grh(dev, ah, mac, &is_mcast, port);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
memcpy(path->dmac, mac, 6);
|
||||
memcpy(path->dmac, ah->dmac, ETH_ALEN);
|
||||
path->ackto = MLX4_IB_LINK_TYPE_ETH;
|
||||
/* use index 0 into MAC table for IBoE */
|
||||
path->grh_mylmc &= 0x80;
|
||||
/* find the index into MAC table for IBoE */
|
||||
if (!is_zero_ether_addr((const u8 *)&smac)) {
|
||||
if (mlx4_find_cached_mac(dev->dev, port, smac,
|
||||
&smac_index))
|
||||
return -ENOENT;
|
||||
} else {
|
||||
smac_index = 0;
|
||||
}
|
||||
|
||||
vlan_tag = rdma_get_vlan_id(&dev->iboe.gid_table[port - 1][ah->grh.sgid_index]);
|
||||
path->grh_mylmc &= 0x80 | smac_index;
|
||||
|
||||
path->feup |= MLX4_FEUP_FORCE_ETH_UP;
|
||||
if (vlan_tag < 0x1000) {
|
||||
if (mlx4_find_cached_vlan(dev->dev, port, vlan_tag, &vidx))
|
||||
return -ENOENT;
|
||||
|
||||
path->vlan_index = vidx;
|
||||
path->fl = 1 << 6;
|
||||
path->feup |= MLX4_FVL_FORCE_ETH_VLAN;
|
||||
}
|
||||
} else
|
||||
path->sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE |
|
||||
@@ -1239,6 +1258,28 @@ static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_ah_attr *ah,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlx4_set_path(struct mlx4_ib_dev *dev, const struct ib_qp_attr *qp,
|
||||
enum ib_qp_attr_mask qp_attr_mask,
|
||||
struct mlx4_qp_path *path, u8 port)
|
||||
{
|
||||
return _mlx4_set_path(dev, &qp->ah_attr,
|
||||
mlx4_mac_to_u64((u8 *)qp->smac),
|
||||
(qp_attr_mask & IB_QP_VID) ? qp->vlan_id : 0xffff,
|
||||
path, port);
|
||||
}
|
||||
|
||||
static int mlx4_set_alt_path(struct mlx4_ib_dev *dev,
|
||||
const struct ib_qp_attr *qp,
|
||||
enum ib_qp_attr_mask qp_attr_mask,
|
||||
struct mlx4_qp_path *path, u8 port)
|
||||
{
|
||||
return _mlx4_set_path(dev, &qp->alt_ah_attr,
|
||||
mlx4_mac_to_u64((u8 *)qp->alt_smac),
|
||||
(qp_attr_mask & IB_QP_ALT_VID) ?
|
||||
qp->alt_vlan_id : 0xffff,
|
||||
path, port);
|
||||
}
|
||||
|
||||
static void update_mcg_macs(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp)
|
||||
{
|
||||
struct mlx4_ib_gid_entry *ge, *tmp;
|
||||
@@ -1362,7 +1403,7 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
|
||||
}
|
||||
|
||||
if (attr_mask & IB_QP_AV) {
|
||||
if (mlx4_set_path(dev, &attr->ah_attr, &context->pri_path,
|
||||
if (mlx4_set_path(dev, attr, attr_mask, &context->pri_path,
|
||||
attr_mask & IB_QP_PORT ?
|
||||
attr->port_num : qp->port))
|
||||
goto out;
|
||||
@@ -1385,8 +1426,8 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
|
||||
dev->dev->caps.pkey_table_len[attr->alt_port_num])
|
||||
goto out;
|
||||
|
||||
if (mlx4_set_path(dev, &attr->alt_ah_attr, &context->alt_path,
|
||||
attr->alt_port_num))
|
||||
if (mlx4_set_alt_path(dev, attr, attr_mask, &context->alt_path,
|
||||
attr->alt_port_num))
|
||||
goto out;
|
||||
|
||||
context->alt_path.pkey_index = attr->alt_pkey_index;
|
||||
@@ -1497,6 +1538,17 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
|
||||
context->pri_path.ackto = (context->pri_path.ackto & 0xf8) |
|
||||
MLX4_IB_LINK_TYPE_ETH;
|
||||
|
||||
if (ibqp->qp_type == IB_QPT_UD && (new_state == IB_QPS_RTR)) {
|
||||
int is_eth = rdma_port_get_link_layer(
|
||||
&dev->ib_dev, qp->port) ==
|
||||
IB_LINK_LAYER_ETHERNET;
|
||||
if (is_eth) {
|
||||
context->pri_path.ackto = MLX4_IB_LINK_TYPE_ETH;
|
||||
optpar |= MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cur_state == IB_QPS_RTS && new_state == IB_QPS_SQD &&
|
||||
attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY && attr->en_sqd_async_notify)
|
||||
sqd_event = 1;
|
||||
@@ -1599,13 +1651,21 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
|
||||
struct mlx4_ib_qp *qp = to_mqp(ibqp);
|
||||
enum ib_qp_state cur_state, new_state;
|
||||
int err = -EINVAL;
|
||||
|
||||
int ll;
|
||||
mutex_lock(&qp->mutex);
|
||||
|
||||
cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;
|
||||
new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;
|
||||
|
||||
if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type, attr_mask)) {
|
||||
if (cur_state == new_state && cur_state == IB_QPS_RESET) {
|
||||
ll = IB_LINK_LAYER_UNSPECIFIED;
|
||||
} else {
|
||||
int port = attr_mask & IB_QP_PORT ? attr->port_num : qp->port;
|
||||
ll = rdma_port_get_link_layer(&dev->ib_dev, port);
|
||||
}
|
||||
|
||||
if (!ib_modify_qp_is_ok(cur_state, new_state, ibqp->qp_type,
|
||||
attr_mask, ll)) {
|
||||
pr_debug("qpn 0x%x: invalid attribute mask specified "
|
||||
"for transition %d to %d. qp_type %d,"
|
||||
" attr_mask 0x%x\n",
|
||||
@@ -1822,8 +1882,10 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr,
|
||||
return err;
|
||||
}
|
||||
|
||||
vlan = rdma_get_vlan_id(&sgid);
|
||||
is_vlan = vlan < 0x1000;
|
||||
if (ah->av.eth.vlan != 0xffff) {
|
||||
vlan = be16_to_cpu(ah->av.eth.vlan) & 0x0fff;
|
||||
is_vlan = 1;
|
||||
}
|
||||
}
|
||||
ib_ud_header_init(send_size, !is_eth, is_eth, is_vlan, is_grh, 0, &sqp->ud_header);
|
||||
|
||||
|
Reference in New Issue
Block a user