Commit 6d06c9aa authored by Guy Levi's avatar Guy Levi Committed by Jason Gunthorpe

IB/mlx4: Add Scatter FCS support over WQ creation

As a default, for Ethernet packets, the device scatters only the payload
of ingress packets. The scatter FCS feature lets the user to get the FCS
(Ethernet's frame check sequence) in the received WR's buffer as a 4
Bytes trailer following the packet's payload.
Reviewed-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarGuy Levi <guyle@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 9c71172c
...@@ -559,16 +559,21 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, ...@@ -559,16 +559,21 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
props->timestamp_mask = 0xFFFFFFFFFFFFULL; props->timestamp_mask = 0xFFFFFFFFFFFFULL;
props->max_ah = INT_MAX; props->max_ah = INT_MAX;
if ((dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS) && if (mlx4_ib_port_link_layer(ibdev, 1) == IB_LINK_LAYER_ETHERNET ||
(mlx4_ib_port_link_layer(ibdev, 1) == IB_LINK_LAYER_ETHERNET || mlx4_ib_port_link_layer(ibdev, 2) == IB_LINK_LAYER_ETHERNET) {
mlx4_ib_port_link_layer(ibdev, 2) == IB_LINK_LAYER_ETHERNET)) { if (dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS) {
props->rss_caps.max_rwq_indirection_tables = props->max_qp; props->rss_caps.max_rwq_indirection_tables =
props->max_qp;
props->rss_caps.max_rwq_indirection_table_size = props->rss_caps.max_rwq_indirection_table_size =
dev->dev->caps.max_rss_tbl_sz; dev->dev->caps.max_rss_tbl_sz;
props->rss_caps.supported_qpts = 1 << IB_QPT_RAW_PACKET; props->rss_caps.supported_qpts = 1 << IB_QPT_RAW_PACKET;
props->max_wq_type_rq = props->max_qp; props->max_wq_type_rq = props->max_qp;
} }
if (dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_FCS_KEEP)
props->raw_packet_caps |= IB_RAW_PACKET_CAP_SCATTER_FCS;
}
props->cq_caps.max_cq_moderation_count = MLX4_MAX_CQ_COUNT; props->cq_caps.max_cq_moderation_count = MLX4_MAX_CQ_COUNT;
props->cq_caps.max_cq_moderation_period = MLX4_MAX_CQ_PERIOD; props->cq_caps.max_cq_moderation_period = MLX4_MAX_CQ_PERIOD;
......
...@@ -189,6 +189,7 @@ enum mlx4_ib_qp_flags { ...@@ -189,6 +189,7 @@ enum mlx4_ib_qp_flags {
MLX4_IB_QP_LSO = IB_QP_CREATE_IPOIB_UD_LSO, MLX4_IB_QP_LSO = IB_QP_CREATE_IPOIB_UD_LSO,
MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK, MLX4_IB_QP_BLOCK_MULTICAST_LOOPBACK = IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK,
MLX4_IB_QP_NETIF = IB_QP_CREATE_NETIF_QP, MLX4_IB_QP_NETIF = IB_QP_CREATE_NETIF_QP,
MLX4_IB_QP_SCATTER_FCS = IB_QP_CREATE_SCATTER_FCS,
/* Mellanox specific flags start from IB_QP_CREATE_RESERVED_START */ /* Mellanox specific flags start from IB_QP_CREATE_RESERVED_START */
MLX4_IB_ROCE_V2_GSI_QP = MLX4_IB_QP_CREATE_ROCE_V2_GSI, MLX4_IB_ROCE_V2_GSI_QP = MLX4_IB_QP_CREATE_ROCE_V2_GSI,
......
...@@ -1096,6 +1096,17 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd, ...@@ -1096,6 +1096,17 @@ static int create_qp_common(struct mlx4_ib_dev *dev, struct ib_pd *pd,
qp->inl_recv_sz = ucmd.qp.inl_recv_sz; qp->inl_recv_sz = ucmd.qp.inl_recv_sz;
} }
if (init_attr->create_flags & IB_QP_CREATE_SCATTER_FCS) {
if (!(dev->dev->caps.flags &
MLX4_DEV_CAP_FLAG_FCS_KEEP)) {
pr_debug("scatter FCS is unsupported\n");
err = -EOPNOTSUPP;
goto err;
}
qp->flags |= MLX4_IB_QP_SCATTER_FCS;
}
err = set_rq_size(dev, &init_attr->cap, !!pd->uobject, err = set_rq_size(dev, &init_attr->cap, !!pd->uobject,
qp_has_rq(init_attr), qp, qp->inl_recv_sz); qp_has_rq(init_attr), qp, qp->inl_recv_sz);
if (err) if (err)
...@@ -2234,6 +2245,9 @@ static int __mlx4_ib_modify_qp(void *src, enum mlx4_ib_source_type src_type, ...@@ -2234,6 +2245,9 @@ static int __mlx4_ib_modify_qp(void *src, enum mlx4_ib_source_type src_type,
if (qp->inl_recv_sz) if (qp->inl_recv_sz)
context->param3 |= cpu_to_be32(1 << 25); context->param3 |= cpu_to_be32(1 << 25);
if (qp->flags & MLX4_IB_QP_SCATTER_FCS)
context->param3 |= cpu_to_be32(1 << 29);
if (qp_type == IB_QPT_GSI || qp_type == IB_QPT_SMI) if (qp_type == IB_QPT_GSI || qp_type == IB_QPT_SMI)
context->mtu_msgmax = (IB_MTU_4096 << 5) | 11; context->mtu_msgmax = (IB_MTU_4096 << 5) | 11;
else if (qp_type == IB_QPT_RAW_PACKET) else if (qp_type == IB_QPT_RAW_PACKET)
...@@ -4204,7 +4218,7 @@ struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd, ...@@ -4204,7 +4218,7 @@ struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd,
return ERR_PTR(-EOPNOTSUPP); return ERR_PTR(-EOPNOTSUPP);
} }
if (init_attr->create_flags) { if (init_attr->create_flags & ~IB_WQ_FLAGS_SCATTER_FCS) {
pr_debug("unsupported create_flags %u\n", pr_debug("unsupported create_flags %u\n",
init_attr->create_flags); init_attr->create_flags);
return ERR_PTR(-EOPNOTSUPP); return ERR_PTR(-EOPNOTSUPP);
...@@ -4225,6 +4239,9 @@ struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd, ...@@ -4225,6 +4239,9 @@ struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd,
ib_qp_init_attr.recv_cq = init_attr->cq; ib_qp_init_attr.recv_cq = init_attr->cq;
ib_qp_init_attr.send_cq = ib_qp_init_attr.recv_cq; /* Dummy CQ */ ib_qp_init_attr.send_cq = ib_qp_init_attr.recv_cq; /* Dummy CQ */
if (init_attr->create_flags & IB_WQ_FLAGS_SCATTER_FCS)
ib_qp_init_attr.create_flags |= IB_QP_CREATE_SCATTER_FCS;
err = create_qp_common(dev, pd, MLX4_IB_RWQ_SRC, &ib_qp_init_attr, err = create_qp_common(dev, pd, MLX4_IB_RWQ_SRC, &ib_qp_init_attr,
udata, 0, &qp); udata, 0, &qp);
if (err) { if (err) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment