IB/mlx4: Add support for modifying CQ moderation parameters
[linux-2.6-block.git] / drivers / infiniband / hw / mlx4 / cq.c
index 7360bbafbe84ec9883b665913bc76362e7a74196..e4fb64b118e3f73cef3f556d307aa1a52caa6ae0 100644 (file)
@@ -85,6 +85,14 @@ static struct mlx4_cqe *next_cqe_sw(struct mlx4_ib_cq *cq)
        return get_sw_cqe(cq, cq->mcq.cons_index);
 }
 
+int mlx4_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
+{
+       struct mlx4_ib_cq *mcq = to_mcq(cq);
+       struct mlx4_ib_dev *dev = to_mdev(cq->device);
+
+       return mlx4_cq_modify(dev->dev, &mcq->mcq, cq_count, cq_period);
+}
+
 struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector,
                                struct ib_ucontext *context,
                                struct ib_udata *udata)
@@ -297,6 +305,20 @@ static void mlx4_ib_handle_error_cqe(struct mlx4_err_cqe *cqe,
        wc->vendor_err = cqe->vendor_err_syndrome;
 }
 
+static int mlx4_ib_ipoib_csum_ok(__be32 status, __be16 checksum)
+{
+       return ((status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_IPV4        |
+                                     MLX4_CQE_IPOIB_STATUS_IPV4F       |
+                                     MLX4_CQE_IPOIB_STATUS_IPV4OPT     |
+                                     MLX4_CQE_IPOIB_STATUS_IPV6        |
+                                     MLX4_CQE_IPOIB_STATUS_IPOK)) ==
+               cpu_to_be32(MLX4_CQE_IPOIB_STATUS_IPV4  |
+                           MLX4_CQE_IPOIB_STATUS_IPOK))                &&
+               (status & cpu_to_be32(MLX4_CQE_IPOIB_STATUS_UDP |
+                                     MLX4_CQE_IPOIB_STATUS_TCP))       &&
+               checksum == cpu_to_be16(0xffff);
+}
+
 static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
                            struct mlx4_ib_qp **cur_qp,
                            struct ib_wc *wc)
@@ -406,6 +428,9 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
                case MLX4_OPCODE_BIND_MW:
                        wc->opcode    = IB_WC_BIND_MW;
                        break;
+               case MLX4_OPCODE_LSO:
+                       wc->opcode    = IB_WC_LSO;
+                       break;
                }
        } else {
                wc->byte_len = be32_to_cpu(cqe->byte_cnt);
@@ -434,6 +459,8 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq,
                wc->dlid_path_bits = (g_mlpath_rqpn >> 24) & 0x7f;
                wc->wc_flags      |= g_mlpath_rqpn & 0x80000000 ? IB_WC_GRH : 0;
                wc->pkey_index     = be32_to_cpu(cqe->immed_rss_invalid) & 0x7f;
+               wc->csum_ok        = mlx4_ib_ipoib_csum_ok(cqe->ipoib_status,
+                                                          cqe->checksum);
        }
 
        return 0;