| .. | .. |
|---|
| 34 | 34 | #include <linux/module.h> |
|---|
| 35 | 35 | #include <linux/hardirq.h> |
|---|
| 36 | 36 | #include <linux/mlx5/driver.h> |
|---|
| 37 | | -#include <linux/mlx5/cmd.h> |
|---|
| 38 | 37 | #include <rdma/ib_verbs.h> |
|---|
| 39 | 38 | #include <linux/mlx5/cq.h> |
|---|
| 40 | 39 | #include "mlx5_core.h" |
|---|
| 40 | +#include "lib/eq.h" |
|---|
| 41 | 41 | |
|---|
| 42 | 42 | #define TASKLET_MAX_TIME 2 |
|---|
| 43 | 43 | #define TASKLET_MAX_TIME_JIFFIES msecs_to_jiffies(TASKLET_MAX_TIME) |
|---|
| 44 | 44 | |
|---|
| 45 | | -void mlx5_cq_tasklet_cb(unsigned long data) |
|---|
| 45 | +void mlx5_cq_tasklet_cb(struct tasklet_struct *t) |
|---|
| 46 | 46 | { |
|---|
| 47 | 47 | unsigned long flags; |
|---|
| 48 | 48 | unsigned long end = jiffies + TASKLET_MAX_TIME_JIFFIES; |
|---|
| 49 | | - struct mlx5_eq_tasklet *ctx = (struct mlx5_eq_tasklet *)data; |
|---|
| 49 | + struct mlx5_eq_tasklet *ctx = from_tasklet(ctx, t, task); |
|---|
| 50 | 50 | struct mlx5_core_cq *mcq; |
|---|
| 51 | 51 | struct mlx5_core_cq *temp; |
|---|
| 52 | 52 | |
|---|
| .. | .. |
|---|
| 57 | 57 | list_for_each_entry_safe(mcq, temp, &ctx->process_list, |
|---|
| 58 | 58 | tasklet_ctx.list) { |
|---|
| 59 | 59 | list_del_init(&mcq->tasklet_ctx.list); |
|---|
| 60 | | - mcq->tasklet_ctx.comp(mcq); |
|---|
| 60 | + mcq->tasklet_ctx.comp(mcq, NULL); |
|---|
| 61 | 61 | mlx5_cq_put(mcq); |
|---|
| 62 | 62 | if (time_after(jiffies, end)) |
|---|
| 63 | 63 | break; |
|---|
| .. | .. |
|---|
| 67 | 67 | tasklet_schedule(&ctx->task); |
|---|
| 68 | 68 | } |
|---|
| 69 | 69 | |
|---|
| 70 | | -static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq) |
|---|
| 70 | +static void mlx5_add_cq_to_tasklet(struct mlx5_core_cq *cq, |
|---|
| 71 | + struct mlx5_eqe *eqe) |
|---|
| 71 | 72 | { |
|---|
| 72 | 73 | unsigned long flags; |
|---|
| 73 | 74 | struct mlx5_eq_tasklet *tasklet_ctx = cq->tasklet_ctx.priv; |
|---|
| .. | .. |
|---|
| 86 | 87 | } |
|---|
| 87 | 88 | |
|---|
| 88 | 89 | int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, |
|---|
| 89 | | - u32 *in, int inlen) |
|---|
| 90 | + u32 *in, int inlen, u32 *out, int outlen) |
|---|
| 90 | 91 | { |
|---|
| 91 | 92 | int eqn = MLX5_GET(cqc, MLX5_ADDR_OF(create_cq_in, in, cq_context), c_eqn); |
|---|
| 92 | | - u32 dout[MLX5_ST_SZ_DW(destroy_cq_out)]; |
|---|
| 93 | | - u32 out[MLX5_ST_SZ_DW(create_cq_out)]; |
|---|
| 94 | | - u32 din[MLX5_ST_SZ_DW(destroy_cq_in)]; |
|---|
| 95 | | - struct mlx5_eq *eq; |
|---|
| 93 | + u32 din[MLX5_ST_SZ_DW(destroy_cq_in)] = {}; |
|---|
| 94 | + struct mlx5_eq_comp *eq; |
|---|
| 96 | 95 | int err; |
|---|
| 97 | 96 | |
|---|
| 98 | | - eq = mlx5_eqn2eq(dev, eqn); |
|---|
| 97 | + eq = mlx5_eqn2comp_eq(dev, eqn); |
|---|
| 99 | 98 | if (IS_ERR(eq)) |
|---|
| 100 | 99 | return PTR_ERR(eq); |
|---|
| 101 | 100 | |
|---|
| 102 | | - memset(out, 0, sizeof(out)); |
|---|
| 101 | + memset(out, 0, outlen); |
|---|
| 103 | 102 | MLX5_SET(create_cq_in, in, opcode, MLX5_CMD_OP_CREATE_CQ); |
|---|
| 104 | | - err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); |
|---|
| 103 | + err = mlx5_cmd_exec(dev, in, inlen, out, outlen); |
|---|
| 105 | 104 | if (err) |
|---|
| 106 | 105 | return err; |
|---|
| 107 | 106 | |
|---|
| .. | .. |
|---|
| 109 | 108 | cq->cons_index = 0; |
|---|
| 110 | 109 | cq->arm_sn = 0; |
|---|
| 111 | 110 | cq->eq = eq; |
|---|
| 111 | + cq->uid = MLX5_GET(create_cq_in, in, uid); |
|---|
| 112 | 112 | refcount_set(&cq->refcount, 1); |
|---|
| 113 | 113 | init_completion(&cq->free); |
|---|
| 114 | 114 | if (!cq->comp) |
|---|
| .. | .. |
|---|
| 118 | 118 | INIT_LIST_HEAD(&cq->tasklet_ctx.list); |
|---|
| 119 | 119 | |
|---|
| 120 | 120 | /* Add to comp EQ CQ tree to recv comp events */ |
|---|
| 121 | | - err = mlx5_eq_add_cq(eq, cq); |
|---|
| 121 | + err = mlx5_eq_add_cq(&eq->core, cq); |
|---|
| 122 | 122 | if (err) |
|---|
| 123 | 123 | goto err_cmd; |
|---|
| 124 | 124 | |
|---|
| 125 | 125 | /* Add to async EQ CQ tree to recv async events */ |
|---|
| 126 | | - err = mlx5_eq_add_cq(&dev->priv.eq_table.async_eq, cq); |
|---|
| 126 | + err = mlx5_eq_add_cq(mlx5_get_async_eq(dev), cq); |
|---|
| 127 | 127 | if (err) |
|---|
| 128 | 128 | goto err_cq_add; |
|---|
| 129 | 129 | |
|---|
| .. | .. |
|---|
| 134 | 134 | cq->cqn); |
|---|
| 135 | 135 | |
|---|
| 136 | 136 | cq->uar = dev->priv.uar; |
|---|
| 137 | + cq->irqn = eq->core.irqn; |
|---|
| 137 | 138 | |
|---|
| 138 | 139 | return 0; |
|---|
| 139 | 140 | |
|---|
| 140 | 141 | err_cq_add: |
|---|
| 141 | | - mlx5_eq_del_cq(eq, cq); |
|---|
| 142 | + mlx5_eq_del_cq(&eq->core, cq); |
|---|
| 142 | 143 | err_cmd: |
|---|
| 143 | | - memset(din, 0, sizeof(din)); |
|---|
| 144 | | - memset(dout, 0, sizeof(dout)); |
|---|
| 145 | 144 | MLX5_SET(destroy_cq_in, din, opcode, MLX5_CMD_OP_DESTROY_CQ); |
|---|
| 146 | 145 | MLX5_SET(destroy_cq_in, din, cqn, cq->cqn); |
|---|
| 147 | | - mlx5_cmd_exec(dev, din, sizeof(din), dout, sizeof(dout)); |
|---|
| 146 | + MLX5_SET(destroy_cq_in, din, uid, cq->uid); |
|---|
| 147 | + mlx5_cmd_exec_in(dev, destroy_cq, din); |
|---|
| 148 | 148 | return err; |
|---|
| 149 | 149 | } |
|---|
| 150 | 150 | EXPORT_SYMBOL(mlx5_core_create_cq); |
|---|
| 151 | 151 | |
|---|
| 152 | 152 | int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq) |
|---|
| 153 | 153 | { |
|---|
| 154 | | - u32 out[MLX5_ST_SZ_DW(destroy_cq_out)] = {0}; |
|---|
| 155 | | - u32 in[MLX5_ST_SZ_DW(destroy_cq_in)] = {0}; |
|---|
| 154 | + u32 in[MLX5_ST_SZ_DW(destroy_cq_in)] = {}; |
|---|
| 156 | 155 | int err; |
|---|
| 157 | 156 | |
|---|
| 158 | | - err = mlx5_eq_del_cq(&dev->priv.eq_table.async_eq, cq); |
|---|
| 159 | | - if (err) |
|---|
| 160 | | - return err; |
|---|
| 157 | + mlx5_debug_cq_remove(dev, cq); |
|---|
| 161 | 158 | |
|---|
| 162 | | - err = mlx5_eq_del_cq(cq->eq, cq); |
|---|
| 163 | | - if (err) |
|---|
| 164 | | - return err; |
|---|
| 159 | + mlx5_eq_del_cq(mlx5_get_async_eq(dev), cq); |
|---|
| 160 | + mlx5_eq_del_cq(&cq->eq->core, cq); |
|---|
| 165 | 161 | |
|---|
| 166 | 162 | MLX5_SET(destroy_cq_in, in, opcode, MLX5_CMD_OP_DESTROY_CQ); |
|---|
| 167 | 163 | MLX5_SET(destroy_cq_in, in, cqn, cq->cqn); |
|---|
| 168 | | - err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); |
|---|
| 164 | + MLX5_SET(destroy_cq_in, in, uid, cq->uid); |
|---|
| 165 | + err = mlx5_cmd_exec_in(dev, destroy_cq, in); |
|---|
| 169 | 166 | if (err) |
|---|
| 170 | 167 | return err; |
|---|
| 171 | 168 | |
|---|
| 172 | 169 | synchronize_irq(cq->irqn); |
|---|
| 173 | | - |
|---|
| 174 | | - mlx5_debug_cq_remove(dev, cq); |
|---|
| 175 | 170 | mlx5_cq_put(cq); |
|---|
| 176 | 171 | wait_for_completion(&cq->free); |
|---|
| 177 | 172 | |
|---|
| .. | .. |
|---|
| 180 | 175 | EXPORT_SYMBOL(mlx5_core_destroy_cq); |
|---|
| 181 | 176 | |
|---|
| 182 | 177 | int mlx5_core_query_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, |
|---|
| 183 | | - u32 *out, int outlen) |
|---|
| 178 | + u32 *out) |
|---|
| 184 | 179 | { |
|---|
| 185 | | - u32 in[MLX5_ST_SZ_DW(query_cq_in)] = {0}; |
|---|
| 180 | + u32 in[MLX5_ST_SZ_DW(query_cq_in)] = {}; |
|---|
| 186 | 181 | |
|---|
| 187 | 182 | MLX5_SET(query_cq_in, in, opcode, MLX5_CMD_OP_QUERY_CQ); |
|---|
| 188 | 183 | MLX5_SET(query_cq_in, in, cqn, cq->cqn); |
|---|
| 189 | | - return mlx5_cmd_exec(dev, in, sizeof(in), out, outlen); |
|---|
| 184 | + return mlx5_cmd_exec_inout(dev, query_cq, in, out); |
|---|
| 190 | 185 | } |
|---|
| 191 | 186 | EXPORT_SYMBOL(mlx5_core_query_cq); |
|---|
| 192 | 187 | |
|---|
| 193 | 188 | int mlx5_core_modify_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, |
|---|
| 194 | 189 | u32 *in, int inlen) |
|---|
| 195 | 190 | { |
|---|
| 196 | | - u32 out[MLX5_ST_SZ_DW(modify_cq_out)] = {0}; |
|---|
| 191 | + u32 out[MLX5_ST_SZ_DW(modify_cq_out)] = {}; |
|---|
| 197 | 192 | |
|---|
| 198 | 193 | MLX5_SET(modify_cq_in, in, opcode, MLX5_CMD_OP_MODIFY_CQ); |
|---|
| 194 | + MLX5_SET(modify_cq_in, in, uid, cq->uid); |
|---|
| 199 | 195 | return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); |
|---|
| 200 | 196 | } |
|---|
| 201 | 197 | EXPORT_SYMBOL(mlx5_core_modify_cq); |
|---|
| .. | .. |
|---|
| 205 | 201 | u16 cq_period, |
|---|
| 206 | 202 | u16 cq_max_count) |
|---|
| 207 | 203 | { |
|---|
| 208 | | - u32 in[MLX5_ST_SZ_DW(modify_cq_in)] = {0}; |
|---|
| 204 | + u32 in[MLX5_ST_SZ_DW(modify_cq_in)] = {}; |
|---|
| 209 | 205 | void *cqc; |
|---|
| 210 | 206 | |
|---|
| 211 | 207 | MLX5_SET(modify_cq_in, in, cqn, cq->cqn); |
|---|