IB/mlx5: Implement fragmented completion queue (CQ)
[linux-2.6-block.git] / include / linux / mlx5 / driver.h
index 2860a253275be528fbb9c42e8b42adf31be513f8..bfea26af6de53c9169b48e058ce16cc80a7d72a4 100644 (file)
@@ -345,13 +345,6 @@ struct mlx5_buf_list {
        dma_addr_t              map;
 };
 
-struct mlx5_buf {
-       struct mlx5_buf_list    direct;
-       int                     npages;
-       int                     size;
-       u8                      page_shift;
-};
-
 struct mlx5_frag_buf {
        struct mlx5_buf_list    *frags;
        int                     npages;
@@ -359,6 +352,15 @@ struct mlx5_frag_buf {
        u8                      page_shift;
 };
 
+struct mlx5_frag_buf_ctrl {
+       struct mlx5_frag_buf    frag_buf;
+       u32                     sz_m1;
+       u32                     frag_sz_m1;
+       u8                      log_sz;
+       u8                      log_stride;
+       u8                      log_frag_strides;
+};
+
 struct mlx5_eq_tasklet {
        struct list_head list;
        struct list_head process_list;
@@ -386,7 +388,7 @@ struct mlx5_eq {
        struct mlx5_cq_table    cq_table;
        __be32 __iomem         *doorbell;
        u32                     cons_index;
-       struct mlx5_buf         buf;
+       struct mlx5_frag_buf    buf;
        int                     size;
        unsigned int            irqn;
        u8                      eqn;
@@ -932,9 +934,9 @@ struct mlx5_hca_vport_context {
        bool                    grh_required;
 };
 
-static inline void *mlx5_buf_offset(struct mlx5_buf *buf, int offset)
+static inline void *mlx5_buf_offset(struct mlx5_frag_buf *buf, int offset)
 {
-               return buf->direct.buf + offset;
+               return buf->frags->buf + offset;
 }
 
 #define STRUCT_FIELD(header, field) \
@@ -973,6 +975,25 @@ static inline u32 mlx5_base_mkey(const u32 key)
        return key & 0xffffff00u;
 }
 
+static inline void mlx5_core_init_cq_frag_buf(struct mlx5_frag_buf_ctrl *fbc,
+                                             void *cqc)
+{
+       fbc->log_stride = 6 + MLX5_GET(cqc, cqc, cqe_sz);
+       fbc->log_sz     = MLX5_GET(cqc, cqc, log_cq_size);
+       fbc->sz_m1      = (1 << fbc->log_sz) - 1;
+       fbc->log_frag_strides = PAGE_SHIFT - fbc->log_stride;
+       fbc->frag_sz_m1 = (1 << fbc->log_frag_strides) - 1;
+}
+
+static inline void *mlx5_frag_buf_get_wqe(struct mlx5_frag_buf_ctrl *fbc,
+                                         u32 ix)
+{
+       unsigned int frag = (ix >> fbc->log_frag_strides);
+
+       return fbc->frag_buf.frags[frag].buf +
+               ((fbc->frag_sz_m1 & ix) << fbc->log_stride);
+}
+
 int mlx5_cmd_init(struct mlx5_core_dev *dev);
 void mlx5_cmd_cleanup(struct mlx5_core_dev *dev);
 void mlx5_cmd_use_events(struct mlx5_core_dev *dev);
@@ -998,9 +1019,10 @@ void mlx5_drain_health_wq(struct mlx5_core_dev *dev);
 void mlx5_trigger_health_work(struct mlx5_core_dev *dev);
 void mlx5_drain_health_recovery(struct mlx5_core_dev *dev);
 int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size,
-                       struct mlx5_buf *buf, int node);
-int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, struct mlx5_buf *buf);
-void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_buf *buf);
+                       struct mlx5_frag_buf *buf, int node);
+int mlx5_buf_alloc(struct mlx5_core_dev *dev,
+                  int size, struct mlx5_frag_buf *buf);
+void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf);
 int mlx5_frag_buf_alloc_node(struct mlx5_core_dev *dev, int size,
                             struct mlx5_frag_buf *buf, int node);
 void mlx5_frag_buf_free(struct mlx5_core_dev *dev, struct mlx5_frag_buf *buf);
@@ -1045,7 +1067,8 @@ int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot);
 int mlx5_reclaim_startup_pages(struct mlx5_core_dev *dev);
 void mlx5_register_debugfs(void);
 void mlx5_unregister_debugfs(void);
-void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas);
+
+void mlx5_fill_page_array(struct mlx5_frag_buf *buf, __be64 *pas);
 void mlx5_fill_page_frag_array(struct mlx5_frag_buf *frag_buf, __be64 *pas);
 void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type);
 void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type);