RDMA/mlx5: Expose wqe posting helpers outside of wr.c
[linux-2.6-microblaze.git] / drivers / infiniband / hw / mlx5 / wr.h
index 4f00575..2dc8943 100644 (file)
@@ -41,6 +41,66 @@ static inline void *get_sq_edge(struct mlx5_ib_wq *sq, u32 idx)
        return fragment_end + MLX5_SEND_WQE_BB;
 }
 
+/* handle_post_send_edge - Check if we get to SQ edge. If yes, update to the
+ * next nearby edge and get new address translation for current WQE position.
+ * @sq: SQ buffer.
+ * @seg: Current WQE position (16B aligned).
+ * @wqe_sz: Total current WQE size [16B].
+ * @cur_edge: Updated current edge.
+ */
+static inline void handle_post_send_edge(struct mlx5_ib_wq *sq, void **seg,
+                                        u32 wqe_sz, void **cur_edge)
+{
+       u32 idx;
+
+       if (likely(*seg != *cur_edge))
+               return;
+
+       idx = (sq->cur_post + (wqe_sz >> 2)) & (sq->wqe_cnt - 1);
+       *cur_edge = get_sq_edge(sq, idx);
+
+       *seg = mlx5_frag_buf_get_wqe(&sq->fbc, idx);
+}
+
+/* mlx5r_memcpy_send_wqe - copy data from src to WQE and update the relevant
+ * WQ's pointers. At the end @seg is aligned to 16B regardless the copied size.
+ * @sq: SQ buffer.
+ * @cur_edge: Updated current edge.
+ * @seg: Current WQE position (16B aligned).
+ * @wqe_sz: Total current WQE size [16B].
+ * @src: Pointer to copy from.
+ * @n: Number of bytes to copy.
+ */
+static inline void mlx5r_memcpy_send_wqe(struct mlx5_ib_wq *sq, void **cur_edge,
+                                        void **seg, u32 *wqe_sz,
+                                        const void *src, size_t n)
+{
+       while (likely(n)) {
+               size_t leftlen = *cur_edge - *seg;
+               size_t copysz = min_t(size_t, leftlen, n);
+               size_t stride;
+
+               memcpy(*seg, src, copysz);
+
+               n -= copysz;
+               src += copysz;
+               stride = !n ? ALIGN(copysz, 16) : copysz;
+               *seg += stride;
+               *wqe_sz += stride >> 4;
+               handle_post_send_edge(sq, seg, *wqe_sz, cur_edge);
+       }
+}
+
+int mlx5r_wq_overflow(struct mlx5_ib_wq *wq, int nreq, struct ib_cq *ib_cq);
+int mlx5r_begin_wqe(struct mlx5_ib_qp *qp, void **seg,
+                   struct mlx5_wqe_ctrl_seg **ctrl, unsigned int *idx,
+                   int *size, void **cur_edge, int nreq, __be32 general_id,
+                   bool send_signaled, bool solicited);
+void mlx5r_finish_wqe(struct mlx5_ib_qp *qp, struct mlx5_wqe_ctrl_seg *ctrl,
+                     void *seg, u8 size, void *cur_edge, unsigned int idx,
+                     u64 wr_id, int nreq, u8 fence, u32 mlx5_opcode);
+void mlx5r_ring_db(struct mlx5_ib_qp *qp, unsigned int nreq,
+                  struct mlx5_wqe_ctrl_seg *ctrl);
 int mlx5_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
                      const struct ib_send_wr **bad_wr, bool drain);
 int mlx5_ib_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr,