net/mlx5: FWTrace, Use async events chain
[linux-2.6-microblaze.git] / drivers / net / ethernet / mellanox / mlx5 / core / eq.c
1 /*
2  * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #include <linux/interrupt.h>
34 #include <linux/notifier.h>
35 #include <linux/module.h>
36 #include <linux/mlx5/driver.h>
37 #include <linux/mlx5/eq.h>
38 #include <linux/mlx5/cmd.h>
39 #ifdef CONFIG_RFS_ACCEL
40 #include <linux/cpu_rmap.h>
41 #endif
42 #include "mlx5_core.h"
43 #include "lib/eq.h"
44 #include "fpga/core.h"
45 #include "eswitch.h"
46 #include "lib/clock.h"
47 #include "diag/fw_tracer.h"
48
49 enum {
50         MLX5_EQE_OWNER_INIT_VAL = 0x1,
51 };
52
53 enum {
54         MLX5_EQ_STATE_ARMED             = 0x9,
55         MLX5_EQ_STATE_FIRED             = 0xa,
56         MLX5_EQ_STATE_ALWAYS_ARMED      = 0xb,
57 };
58
59 enum {
60         MLX5_EQ_DOORBEL_OFFSET  = 0x40,
61 };
62
63 struct mlx5_irq_info {
64         cpumask_var_t mask;
65         char name[MLX5_MAX_IRQ_NAME];
66         void *context; /* dev_id provided to request_irq */
67 };
68
69 struct mlx5_eq_table {
70         struct list_head        comp_eqs_list;
71         struct mlx5_eq          pages_eq;
72         struct mlx5_eq          cmd_eq;
73         struct mlx5_eq          async_eq;
74
75         struct atomic_notifier_head nh[MLX5_EVENT_TYPE_MAX];
76
77         struct mutex            lock; /* sync async eqs creations */
78         int                     num_comp_vectors;
79         struct mlx5_irq_info    *irq_info;
80 #ifdef CONFIG_RFS_ACCEL
81         struct cpu_rmap         *rmap;
82 #endif
83 };
84
85 #define MLX5_ASYNC_EVENT_MASK ((1ull << MLX5_EVENT_TYPE_PATH_MIG)           | \
86                                (1ull << MLX5_EVENT_TYPE_COMM_EST)           | \
87                                (1ull << MLX5_EVENT_TYPE_SQ_DRAINED)         | \
88                                (1ull << MLX5_EVENT_TYPE_CQ_ERROR)           | \
89                                (1ull << MLX5_EVENT_TYPE_WQ_CATAS_ERROR)     | \
90                                (1ull << MLX5_EVENT_TYPE_PATH_MIG_FAILED)    | \
91                                (1ull << MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR) | \
92                                (1ull << MLX5_EVENT_TYPE_WQ_ACCESS_ERROR)    | \
93                                (1ull << MLX5_EVENT_TYPE_PORT_CHANGE)        | \
94                                (1ull << MLX5_EVENT_TYPE_SRQ_CATAS_ERROR)    | \
95                                (1ull << MLX5_EVENT_TYPE_SRQ_LAST_WQE)       | \
96                                (1ull << MLX5_EVENT_TYPE_SRQ_RQ_LIMIT))
97
98 static int mlx5_cmd_destroy_eq(struct mlx5_core_dev *dev, u8 eqn)
99 {
100         u32 out[MLX5_ST_SZ_DW(destroy_eq_out)] = {0};
101         u32 in[MLX5_ST_SZ_DW(destroy_eq_in)]   = {0};
102
103         MLX5_SET(destroy_eq_in, in, opcode, MLX5_CMD_OP_DESTROY_EQ);
104         MLX5_SET(destroy_eq_in, in, eq_number, eqn);
105         return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
106 }
107
108 static const char *eqe_type_str(u8 type)
109 {
110         switch (type) {
111         case MLX5_EVENT_TYPE_COMP:
112                 return "MLX5_EVENT_TYPE_COMP";
113         case MLX5_EVENT_TYPE_PATH_MIG:
114                 return "MLX5_EVENT_TYPE_PATH_MIG";
115         case MLX5_EVENT_TYPE_COMM_EST:
116                 return "MLX5_EVENT_TYPE_COMM_EST";
117         case MLX5_EVENT_TYPE_SQ_DRAINED:
118                 return "MLX5_EVENT_TYPE_SQ_DRAINED";
119         case MLX5_EVENT_TYPE_SRQ_LAST_WQE:
120                 return "MLX5_EVENT_TYPE_SRQ_LAST_WQE";
121         case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT:
122                 return "MLX5_EVENT_TYPE_SRQ_RQ_LIMIT";
123         case MLX5_EVENT_TYPE_CQ_ERROR:
124                 return "MLX5_EVENT_TYPE_CQ_ERROR";
125         case MLX5_EVENT_TYPE_WQ_CATAS_ERROR:
126                 return "MLX5_EVENT_TYPE_WQ_CATAS_ERROR";
127         case MLX5_EVENT_TYPE_PATH_MIG_FAILED:
128                 return "MLX5_EVENT_TYPE_PATH_MIG_FAILED";
129         case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
130                 return "MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR";
131         case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
132                 return "MLX5_EVENT_TYPE_WQ_ACCESS_ERROR";
133         case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
134                 return "MLX5_EVENT_TYPE_SRQ_CATAS_ERROR";
135         case MLX5_EVENT_TYPE_INTERNAL_ERROR:
136                 return "MLX5_EVENT_TYPE_INTERNAL_ERROR";
137         case MLX5_EVENT_TYPE_PORT_CHANGE:
138                 return "MLX5_EVENT_TYPE_PORT_CHANGE";
139         case MLX5_EVENT_TYPE_GPIO_EVENT:
140                 return "MLX5_EVENT_TYPE_GPIO_EVENT";
141         case MLX5_EVENT_TYPE_PORT_MODULE_EVENT:
142                 return "MLX5_EVENT_TYPE_PORT_MODULE_EVENT";
143         case MLX5_EVENT_TYPE_TEMP_WARN_EVENT:
144                 return "MLX5_EVENT_TYPE_TEMP_WARN_EVENT";
145         case MLX5_EVENT_TYPE_REMOTE_CONFIG:
146                 return "MLX5_EVENT_TYPE_REMOTE_CONFIG";
147         case MLX5_EVENT_TYPE_DB_BF_CONGESTION:
148                 return "MLX5_EVENT_TYPE_DB_BF_CONGESTION";
149         case MLX5_EVENT_TYPE_STALL_EVENT:
150                 return "MLX5_EVENT_TYPE_STALL_EVENT";
151         case MLX5_EVENT_TYPE_CMD:
152                 return "MLX5_EVENT_TYPE_CMD";
153         case MLX5_EVENT_TYPE_PAGE_REQUEST:
154                 return "MLX5_EVENT_TYPE_PAGE_REQUEST";
155         case MLX5_EVENT_TYPE_PAGE_FAULT:
156                 return "MLX5_EVENT_TYPE_PAGE_FAULT";
157         case MLX5_EVENT_TYPE_PPS_EVENT:
158                 return "MLX5_EVENT_TYPE_PPS_EVENT";
159         case MLX5_EVENT_TYPE_NIC_VPORT_CHANGE:
160                 return "MLX5_EVENT_TYPE_NIC_VPORT_CHANGE";
161         case MLX5_EVENT_TYPE_FPGA_ERROR:
162                 return "MLX5_EVENT_TYPE_FPGA_ERROR";
163         case MLX5_EVENT_TYPE_FPGA_QP_ERROR:
164                 return "MLX5_EVENT_TYPE_FPGA_QP_ERROR";
165         case MLX5_EVENT_TYPE_GENERAL_EVENT:
166                 return "MLX5_EVENT_TYPE_GENERAL_EVENT";
167         case MLX5_EVENT_TYPE_DEVICE_TRACER:
168                 return "MLX5_EVENT_TYPE_DEVICE_TRACER";
169         default:
170                 return "Unrecognized event";
171         }
172 }
173
174 static enum mlx5_dev_event port_subtype_event(u8 subtype)
175 {
176         switch (subtype) {
177         case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
178                 return MLX5_DEV_EVENT_PORT_DOWN;
179         case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
180                 return MLX5_DEV_EVENT_PORT_UP;
181         case MLX5_PORT_CHANGE_SUBTYPE_INITIALIZED:
182                 return MLX5_DEV_EVENT_PORT_INITIALIZED;
183         case MLX5_PORT_CHANGE_SUBTYPE_LID:
184                 return MLX5_DEV_EVENT_LID_CHANGE;
185         case MLX5_PORT_CHANGE_SUBTYPE_PKEY:
186                 return MLX5_DEV_EVENT_PKEY_CHANGE;
187         case MLX5_PORT_CHANGE_SUBTYPE_GUID:
188                 return MLX5_DEV_EVENT_GUID_CHANGE;
189         case MLX5_PORT_CHANGE_SUBTYPE_CLIENT_REREG:
190                 return MLX5_DEV_EVENT_CLIENT_REREG;
191         }
192         return -1;
193 }
194
195 static void general_event_handler(struct mlx5_core_dev *dev,
196                                   struct mlx5_eqe *eqe)
197 {
198         switch (eqe->sub_type) {
199         case MLX5_GENERAL_SUBTYPE_DELAY_DROP_TIMEOUT:
200                 if (dev->event)
201                         dev->event(dev, MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT, 0);
202                 break;
203         default:
204                 mlx5_core_dbg(dev, "General event with unrecognized subtype: sub_type %d\n",
205                               eqe->sub_type);
206         }
207 }
208
209 static void mlx5_temp_warning_event(struct mlx5_core_dev *dev,
210                                     struct mlx5_eqe *eqe)
211 {
212         u64 value_lsb;
213         u64 value_msb;
214
215         value_lsb = be64_to_cpu(eqe->data.temp_warning.sensor_warning_lsb);
216         value_msb = be64_to_cpu(eqe->data.temp_warning.sensor_warning_msb);
217
218         mlx5_core_warn(dev,
219                        "High temperature on sensors with bit set %llx %llx",
220                        value_msb, value_lsb);
221 }
222
223 /* caller must eventually call mlx5_cq_put on the returned cq */
224 static struct mlx5_core_cq *mlx5_eq_cq_get(struct mlx5_eq *eq, u32 cqn)
225 {
226         struct mlx5_cq_table *table = &eq->cq_table;
227         struct mlx5_core_cq *cq = NULL;
228
229         spin_lock(&table->lock);
230         cq = radix_tree_lookup(&table->tree, cqn);
231         if (likely(cq))
232                 mlx5_cq_hold(cq);
233         spin_unlock(&table->lock);
234
235         return cq;
236 }
237
238 static void mlx5_eq_cq_event(struct mlx5_eq *eq, u32 cqn, int event_type)
239 {
240         struct mlx5_core_cq *cq = mlx5_eq_cq_get(eq, cqn);
241
242         if (unlikely(!cq)) {
243                 mlx5_core_warn(eq->dev, "Async event for bogus CQ 0x%x\n", cqn);
244                 return;
245         }
246
247         cq->event(cq, event_type);
248
249         mlx5_cq_put(cq);
250 }
251
252 static irqreturn_t mlx5_eq_comp_int(int irq, void *eq_ptr)
253 {
254         struct mlx5_eq_comp *eq_comp = eq_ptr;
255         struct mlx5_eq *eq = eq_ptr;
256         struct mlx5_eqe *eqe;
257         int set_ci = 0;
258         u32 cqn = -1;
259
260         while ((eqe = next_eqe_sw(eq))) {
261                 struct mlx5_core_cq *cq;
262                 /* Make sure we read EQ entry contents after we've
263                  * checked the ownership bit.
264                  */
265                 dma_rmb();
266                 /* Assume (eqe->type) is always MLX5_EVENT_TYPE_COMP */
267                 cqn = be32_to_cpu(eqe->data.comp.cqn) & 0xffffff;
268
269                 cq = mlx5_eq_cq_get(eq, cqn);
270                 if (likely(cq)) {
271                         ++cq->arm_sn;
272                         cq->comp(cq);
273                         mlx5_cq_put(cq);
274                 } else {
275                         mlx5_core_warn(eq->dev, "Completion event for bogus CQ 0x%x\n", cqn);
276                 }
277
278                 ++eq->cons_index;
279                 ++set_ci;
280
281                 /* The HCA will think the queue has overflowed if we
282                  * don't tell it we've been processing events.  We
283                  * create our EQs with MLX5_NUM_SPARE_EQE extra
284                  * entries, so we must update our consumer index at
285                  * least that often.
286                  */
287                 if (unlikely(set_ci >= MLX5_NUM_SPARE_EQE)) {
288                         eq_update_ci(eq, 0);
289                         set_ci = 0;
290                 }
291         }
292
293         eq_update_ci(eq, 1);
294
295         if (cqn != -1)
296                 tasklet_schedule(&eq_comp->tasklet_ctx.task);
297
298         return IRQ_HANDLED;
299 }
300
301 /* Some architectures don't latch interrupts when they are disabled, so using
302  * mlx5_eq_poll_irq_disabled could end up losing interrupts while trying to
303  * avoid losing them.  It is not recommended to use it, unless this is the last
304  * resort.
305  */
306 u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq_comp *eq)
307 {
308         u32 count_eqe;
309
310         disable_irq(eq->core.irqn);
311         count_eqe = eq->core.cons_index;
312         mlx5_eq_comp_int(eq->core.irqn, eq);
313         count_eqe = eq->core.cons_index - count_eqe;
314         enable_irq(eq->core.irqn);
315
316         return count_eqe;
317 }
318
319 static irqreturn_t mlx5_eq_async_int(int irq, void *eq_ptr)
320 {
321         struct mlx5_eq *eq = eq_ptr;
322         struct mlx5_eq_table *eqt;
323         struct mlx5_core_dev *dev;
324         struct mlx5_eqe *eqe;
325         int set_ci = 0;
326         u32 cqn = -1;
327         u32 rsn;
328         u8 port;
329
330         dev = eq->dev;
331         eqt = dev->priv.eq_table;
332
333         while ((eqe = next_eqe_sw(eq))) {
334                 /*
335                  * Make sure we read EQ entry contents after we've
336                  * checked the ownership bit.
337                  */
338                 dma_rmb();
339
340                 mlx5_core_dbg(eq->dev, "eqn %d, eqe type %s\n",
341                               eq->eqn, eqe_type_str(eqe->type));
342                 switch (eqe->type) {
343                 case MLX5_EVENT_TYPE_DCT_DRAINED:
344                         rsn = be32_to_cpu(eqe->data.dct.dctn) & 0xffffff;
345                         rsn |= (MLX5_RES_DCT << MLX5_USER_INDEX_LEN);
346                         mlx5_rsc_event(dev, rsn, eqe->type);
347                         break;
348                 case MLX5_EVENT_TYPE_PATH_MIG:
349                 case MLX5_EVENT_TYPE_COMM_EST:
350                 case MLX5_EVENT_TYPE_SQ_DRAINED:
351                 case MLX5_EVENT_TYPE_SRQ_LAST_WQE:
352                 case MLX5_EVENT_TYPE_WQ_CATAS_ERROR:
353                 case MLX5_EVENT_TYPE_PATH_MIG_FAILED:
354                 case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
355                 case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:
356                         rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
357                         rsn |= (eqe->data.qp_srq.type << MLX5_USER_INDEX_LEN);
358                         mlx5_core_dbg(dev, "event %s(%d) arrived on resource 0x%x\n",
359                                       eqe_type_str(eqe->type), eqe->type, rsn);
360                         mlx5_rsc_event(dev, rsn, eqe->type);
361                         break;
362
363                 case MLX5_EVENT_TYPE_SRQ_RQ_LIMIT:
364                 case MLX5_EVENT_TYPE_SRQ_CATAS_ERROR:
365                         rsn = be32_to_cpu(eqe->data.qp_srq.qp_srq_n) & 0xffffff;
366                         mlx5_core_dbg(dev, "SRQ event %s(%d): srqn 0x%x\n",
367                                       eqe_type_str(eqe->type), eqe->type, rsn);
368                         mlx5_srq_event(dev, rsn, eqe->type);
369                         break;
370
371                 case MLX5_EVENT_TYPE_CMD:
372                         mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector), false);
373                         break;
374
375                 case MLX5_EVENT_TYPE_PORT_CHANGE:
376                         port = (eqe->data.port.port >> 4) & 0xf;
377                         switch (eqe->sub_type) {
378                         case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
379                         case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
380                         case MLX5_PORT_CHANGE_SUBTYPE_LID:
381                         case MLX5_PORT_CHANGE_SUBTYPE_PKEY:
382                         case MLX5_PORT_CHANGE_SUBTYPE_GUID:
383                         case MLX5_PORT_CHANGE_SUBTYPE_CLIENT_REREG:
384                         case MLX5_PORT_CHANGE_SUBTYPE_INITIALIZED:
385                                 if (dev->event)
386                                         dev->event(dev, port_subtype_event(eqe->sub_type),
387                                                    (unsigned long)port);
388                                 break;
389                         default:
390                                 mlx5_core_warn(dev, "Port event with unrecognized subtype: port %d, sub_type %d\n",
391                                                port, eqe->sub_type);
392                         }
393                         break;
394                 case MLX5_EVENT_TYPE_CQ_ERROR:
395                         cqn = be32_to_cpu(eqe->data.cq_err.cqn) & 0xffffff;
396                         mlx5_core_warn(dev, "CQ error on CQN 0x%x, syndrome 0x%x\n",
397                                        cqn, eqe->data.cq_err.syndrome);
398                         mlx5_eq_cq_event(eq, cqn, eqe->type);
399                         break;
400
401                 case MLX5_EVENT_TYPE_PAGE_REQUEST:
402                         {
403                                 u16 func_id = be16_to_cpu(eqe->data.req_pages.func_id);
404                                 s32 npages = be32_to_cpu(eqe->data.req_pages.num_pages);
405
406                                 mlx5_core_dbg(dev, "page request for func 0x%x, npages %d\n",
407                                               func_id, npages);
408                                 mlx5_core_req_pages_handler(dev, func_id, npages);
409                         }
410                         break;
411
412                 case MLX5_EVENT_TYPE_NIC_VPORT_CHANGE:
413                         mlx5_eswitch_vport_event(dev->priv.eswitch, eqe);
414                         break;
415
416                 case MLX5_EVENT_TYPE_PORT_MODULE_EVENT:
417                         mlx5_port_module_event(dev, eqe);
418                         break;
419
420                 case MLX5_EVENT_TYPE_PPS_EVENT:
421                         mlx5_pps_event(dev, eqe);
422                         break;
423
424                 case MLX5_EVENT_TYPE_FPGA_ERROR:
425                 case MLX5_EVENT_TYPE_FPGA_QP_ERROR:
426                         mlx5_fpga_event(dev, eqe->type, &eqe->data.raw);
427                         break;
428
429                 case MLX5_EVENT_TYPE_TEMP_WARN_EVENT:
430                         mlx5_temp_warning_event(dev, eqe);
431                         break;
432
433                 case MLX5_EVENT_TYPE_GENERAL_EVENT:
434                         general_event_handler(dev, eqe);
435                         break;
436
437                 default:
438                         mlx5_core_warn(dev, "Unhandled event 0x%x on EQ 0x%x\n",
439                                        eqe->type, eq->eqn);
440                         break;
441                 }
442
443                 if (likely(eqe->type < MLX5_EVENT_TYPE_MAX))
444                         atomic_notifier_call_chain(&eqt->nh[eqe->type], eqe->type, eqe);
445                 else
446                         mlx5_core_warn_once(dev, "notifier_call_chain is not setup for eqe: %d\n", eqe->type);
447
448                 atomic_notifier_call_chain(&eqt->nh[MLX5_EVENT_TYPE_NOTIFY_ANY], eqe->type, eqe);
449
450                 ++eq->cons_index;
451                 ++set_ci;
452
453                 /* The HCA will think the queue has overflowed if we
454                  * don't tell it we've been processing events.  We
455                  * create our EQs with MLX5_NUM_SPARE_EQE extra
456                  * entries, so we must update our consumer index at
457                  * least that often.
458                  */
459                 if (unlikely(set_ci >= MLX5_NUM_SPARE_EQE)) {
460                         eq_update_ci(eq, 0);
461                         set_ci = 0;
462                 }
463         }
464
465         eq_update_ci(eq, 1);
466
467         return IRQ_HANDLED;
468 }
469
470 static void init_eq_buf(struct mlx5_eq *eq)
471 {
472         struct mlx5_eqe *eqe;
473         int i;
474
475         for (i = 0; i < eq->nent; i++) {
476                 eqe = get_eqe(eq, i);
477                 eqe->owner = MLX5_EQE_OWNER_INIT_VAL;
478         }
479 }
480
481 static int
482 create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, const char *name,
483               struct mlx5_eq_param *param)
484 {
485         struct mlx5_eq_table *eq_table = dev->priv.eq_table;
486         struct mlx5_cq_table *cq_table = &eq->cq_table;
487         u32 out[MLX5_ST_SZ_DW(create_eq_out)] = {0};
488         struct mlx5_priv *priv = &dev->priv;
489         u8 vecidx = param->index;
490         __be64 *pas;
491         void *eqc;
492         int inlen;
493         u32 *in;
494         int err;
495
496         if (eq_table->irq_info[vecidx].context)
497                 return -EEXIST;
498
499         /* Init CQ table */
500         memset(cq_table, 0, sizeof(*cq_table));
501         spin_lock_init(&cq_table->lock);
502         INIT_RADIX_TREE(&cq_table->tree, GFP_ATOMIC);
503
504         eq->nent = roundup_pow_of_two(param->nent + MLX5_NUM_SPARE_EQE);
505         eq->cons_index = 0;
506         err = mlx5_buf_alloc(dev, eq->nent * MLX5_EQE_SIZE, &eq->buf);
507         if (err)
508                 return err;
509
510         init_eq_buf(eq);
511
512         inlen = MLX5_ST_SZ_BYTES(create_eq_in) +
513                 MLX5_FLD_SZ_BYTES(create_eq_in, pas[0]) * eq->buf.npages;
514
515         in = kvzalloc(inlen, GFP_KERNEL);
516         if (!in) {
517                 err = -ENOMEM;
518                 goto err_buf;
519         }
520
521         pas = (__be64 *)MLX5_ADDR_OF(create_eq_in, in, pas);
522         mlx5_fill_page_array(&eq->buf, pas);
523
524         MLX5_SET(create_eq_in, in, opcode, MLX5_CMD_OP_CREATE_EQ);
525         MLX5_SET64(create_eq_in, in, event_bitmask, param->mask);
526
527         eqc = MLX5_ADDR_OF(create_eq_in, in, eq_context_entry);
528         MLX5_SET(eqc, eqc, log_eq_size, ilog2(eq->nent));
529         MLX5_SET(eqc, eqc, uar_page, priv->uar->index);
530         MLX5_SET(eqc, eqc, intr, vecidx);
531         MLX5_SET(eqc, eqc, log_page_size,
532                  eq->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
533
534         err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
535         if (err)
536                 goto err_in;
537
538         snprintf(eq_table->irq_info[vecidx].name, MLX5_MAX_IRQ_NAME, "%s@pci:%s",
539                  name, pci_name(dev->pdev));
540         eq_table->irq_info[vecidx].context = param->context;
541
542         eq->vecidx = vecidx;
543         eq->eqn = MLX5_GET(create_eq_out, out, eq_number);
544         eq->irqn = pci_irq_vector(dev->pdev, vecidx);
545         eq->dev = dev;
546         eq->doorbell = priv->uar->map + MLX5_EQ_DOORBEL_OFFSET;
547         err = request_irq(eq->irqn, param->handler, 0,
548                           eq_table->irq_info[vecidx].name, param->context);
549         if (err)
550                 goto err_eq;
551
552         err = mlx5_debug_eq_add(dev, eq);
553         if (err)
554                 goto err_irq;
555
556         /* EQs are created in ARMED state
557          */
558         eq_update_ci(eq, 1);
559
560         kvfree(in);
561         return 0;
562
563 err_irq:
564         free_irq(eq->irqn, eq);
565
566 err_eq:
567         mlx5_cmd_destroy_eq(dev, eq->eqn);
568
569 err_in:
570         kvfree(in);
571
572 err_buf:
573         mlx5_buf_free(dev, &eq->buf);
574         return err;
575 }
576
577 static int destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
578 {
579         struct mlx5_eq_table *eq_table = dev->priv.eq_table;
580         struct mlx5_irq_info *irq_info;
581         int err;
582
583         irq_info = &eq_table->irq_info[eq->vecidx];
584
585         mlx5_debug_eq_remove(dev, eq);
586
587         free_irq(eq->irqn, irq_info->context);
588         irq_info->context = NULL;
589
590         err = mlx5_cmd_destroy_eq(dev, eq->eqn);
591         if (err)
592                 mlx5_core_warn(dev, "failed to destroy a previously created eq: eqn %d\n",
593                                eq->eqn);
594         synchronize_irq(eq->irqn);
595
596         mlx5_buf_free(dev, &eq->buf);
597
598         return err;
599 }
600
601 int mlx5_eq_add_cq(struct mlx5_eq *eq, struct mlx5_core_cq *cq)
602 {
603         struct mlx5_cq_table *table = &eq->cq_table;
604         int err;
605
606         spin_lock_irq(&table->lock);
607         err = radix_tree_insert(&table->tree, cq->cqn, cq);
608         spin_unlock_irq(&table->lock);
609
610         return err;
611 }
612
613 int mlx5_eq_del_cq(struct mlx5_eq *eq, struct mlx5_core_cq *cq)
614 {
615         struct mlx5_cq_table *table = &eq->cq_table;
616         struct mlx5_core_cq *tmp;
617
618         spin_lock_irq(&table->lock);
619         tmp = radix_tree_delete(&table->tree, cq->cqn);
620         spin_unlock_irq(&table->lock);
621
622         if (!tmp) {
623                 mlx5_core_warn(eq->dev, "cq 0x%x not found in eq 0x%x tree\n", eq->eqn, cq->cqn);
624                 return -ENOENT;
625         }
626
627         if (tmp != cq) {
628                 mlx5_core_warn(eq->dev, "corruption on cqn 0x%x in eq 0x%x\n", eq->eqn, cq->cqn);
629                 return -EINVAL;
630         }
631
632         return 0;
633 }
634
635 int mlx5_eq_table_init(struct mlx5_core_dev *dev)
636 {
637         struct mlx5_eq_table *eq_table;
638         int i, err;
639
640         eq_table = kvzalloc(sizeof(*eq_table), GFP_KERNEL);
641         if (!eq_table)
642                 return -ENOMEM;
643
644         dev->priv.eq_table = eq_table;
645
646         err = mlx5_eq_debugfs_init(dev);
647         if (err)
648                 goto kvfree_eq_table;
649
650         mutex_init(&eq_table->lock);
651         for (i = 0; i < MLX5_EVENT_TYPE_MAX; i++)
652                 ATOMIC_INIT_NOTIFIER_HEAD(&eq_table->nh[i]);
653
654         return 0;
655
656 kvfree_eq_table:
657         kvfree(eq_table);
658         dev->priv.eq_table = NULL;
659         return err;
660 }
661
662 void mlx5_eq_table_cleanup(struct mlx5_core_dev *dev)
663 {
664         mlx5_eq_debugfs_cleanup(dev);
665         kvfree(dev->priv.eq_table);
666 }
667
668 /* Async EQs */
669
670 static int create_async_eq(struct mlx5_core_dev *dev, const char *name,
671                            struct mlx5_eq *eq, struct mlx5_eq_param *param)
672 {
673         struct mlx5_eq_table *eq_table = dev->priv.eq_table;
674         int err;
675
676         mutex_lock(&eq_table->lock);
677         if (param->index >= MLX5_EQ_MAX_ASYNC_EQS) {
678                 err = -ENOSPC;
679                 goto unlock;
680         }
681
682         err = create_map_eq(dev, eq, name, param);
683 unlock:
684         mutex_unlock(&eq_table->lock);
685         return err;
686 }
687
688 static int destroy_async_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
689 {
690         struct mlx5_eq_table *eq_table = dev->priv.eq_table;
691         int err;
692
693         mutex_lock(&eq_table->lock);
694         err = destroy_unmap_eq(dev, eq);
695         mutex_unlock(&eq_table->lock);
696         return err;
697 }
698
699 static u64 gather_async_events_mask(struct mlx5_core_dev *dev)
700 {
701         u64 async_event_mask = MLX5_ASYNC_EVENT_MASK;
702
703         if (MLX5_VPORT_MANAGER(dev))
704                 async_event_mask |= (1ull << MLX5_EVENT_TYPE_NIC_VPORT_CHANGE);
705
706         if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH &&
707             MLX5_CAP_GEN(dev, general_notification_event))
708                 async_event_mask |= (1ull << MLX5_EVENT_TYPE_GENERAL_EVENT);
709
710         if (MLX5_CAP_GEN(dev, port_module_event))
711                 async_event_mask |= (1ull << MLX5_EVENT_TYPE_PORT_MODULE_EVENT);
712         else
713                 mlx5_core_dbg(dev, "port_module_event is not set\n");
714
715         if (MLX5_PPS_CAP(dev))
716                 async_event_mask |= (1ull << MLX5_EVENT_TYPE_PPS_EVENT);
717
718         if (MLX5_CAP_GEN(dev, fpga))
719                 async_event_mask |= (1ull << MLX5_EVENT_TYPE_FPGA_ERROR) |
720                                     (1ull << MLX5_EVENT_TYPE_FPGA_QP_ERROR);
721         if (MLX5_CAP_GEN_MAX(dev, dct))
722                 async_event_mask |= (1ull << MLX5_EVENT_TYPE_DCT_DRAINED);
723
724         if (MLX5_CAP_GEN(dev, temp_warn_event))
725                 async_event_mask |= (1ull << MLX5_EVENT_TYPE_TEMP_WARN_EVENT);
726
727         if (MLX5_CAP_MCAM_REG(dev, tracer_registers))
728                 async_event_mask |= (1ull << MLX5_EVENT_TYPE_DEVICE_TRACER);
729
730         return async_event_mask;
731 }
732
733 static int create_async_eqs(struct mlx5_core_dev *dev)
734 {
735         struct mlx5_eq_table *table = dev->priv.eq_table;
736         struct mlx5_eq_param param = {};
737         int err;
738
739         param = (struct mlx5_eq_param) {
740                 .index = MLX5_EQ_CMD_IDX,
741                 .mask = 1ull << MLX5_EVENT_TYPE_CMD,
742                 .nent = MLX5_NUM_CMD_EQE,
743                 .context = &table->cmd_eq,
744                 .handler = mlx5_eq_async_int,
745         };
746         err = create_async_eq(dev, "mlx5_cmd_eq", &table->cmd_eq, &param);
747         if (err) {
748                 mlx5_core_warn(dev, "failed to create cmd EQ %d\n", err);
749                 return err;
750         }
751
752         mlx5_cmd_use_events(dev);
753
754         param = (struct mlx5_eq_param) {
755                 .index = MLX5_EQ_ASYNC_IDX,
756                 .mask = gather_async_events_mask(dev),
757                 .nent = MLX5_NUM_ASYNC_EQE,
758                 .context = &table->async_eq,
759                 .handler = mlx5_eq_async_int,
760         };
761         err = create_async_eq(dev, "mlx5_async_eq", &table->async_eq, &param);
762         if (err) {
763                 mlx5_core_warn(dev, "failed to create async EQ %d\n", err);
764                 goto err1;
765         }
766
767         param = (struct mlx5_eq_param) {
768                 .index = MLX5_EQ_PAGEREQ_IDX,
769                 .mask =  1 << MLX5_EVENT_TYPE_PAGE_REQUEST,
770                 .nent = /* TODO: sriov max_vf + */ 1,
771                 .context = &table->pages_eq,
772                 .handler = mlx5_eq_async_int,
773         };
774         err = create_async_eq(dev, "mlx5_pages_eq", &table->pages_eq, &param);
775         if (err) {
776                 mlx5_core_warn(dev, "failed to create pages EQ %d\n", err);
777                 goto err2;
778         }
779
780         return err;
781
782 err2:
783         destroy_async_eq(dev, &table->async_eq);
784
785 err1:
786         mlx5_cmd_use_polling(dev);
787         destroy_async_eq(dev, &table->cmd_eq);
788         return err;
789 }
790
791 static void destroy_async_eqs(struct mlx5_core_dev *dev)
792 {
793         struct mlx5_eq_table *table = dev->priv.eq_table;
794         int err;
795
796         err = destroy_async_eq(dev, &table->pages_eq);
797         if (err)
798                 mlx5_core_err(dev, "failed to destroy pages eq, err(%d)\n",
799                               err);
800
801         err = destroy_async_eq(dev, &table->async_eq);
802         if (err)
803                 mlx5_core_err(dev, "failed to destroy async eq, err(%d)\n",
804                               err);
805         mlx5_cmd_use_polling(dev);
806
807         err = destroy_async_eq(dev, &table->cmd_eq);
808         if (err)
809                 mlx5_core_err(dev, "failed to destroy command eq, err(%d)\n",
810                               err);
811 }
812
813 struct mlx5_eq *mlx5_get_async_eq(struct mlx5_core_dev *dev)
814 {
815         return &dev->priv.eq_table->async_eq;
816 }
817
818 void mlx5_eq_synchronize_async_irq(struct mlx5_core_dev *dev)
819 {
820         synchronize_irq(dev->priv.eq_table->async_eq.irqn);
821 }
822
823 void mlx5_eq_synchronize_cmd_irq(struct mlx5_core_dev *dev)
824 {
825         synchronize_irq(dev->priv.eq_table->cmd_eq.irqn);
826 }
827
828 /* Generic EQ API for mlx5_core consumers
829  * Needed For RDMA ODP EQ for now
830  */
831 struct mlx5_eq *
832 mlx5_eq_create_generic(struct mlx5_core_dev *dev, const char *name,
833                        struct mlx5_eq_param *param)
834 {
835         struct mlx5_eq *eq = kvzalloc(sizeof(*eq), GFP_KERNEL);
836         int err;
837
838         if (!eq)
839                 return ERR_PTR(-ENOMEM);
840
841         err = create_async_eq(dev, name, eq, param);
842         if (err) {
843                 kvfree(eq);
844                 eq = ERR_PTR(err);
845         }
846
847         return eq;
848 }
849 EXPORT_SYMBOL(mlx5_eq_create_generic);
850
851 int mlx5_eq_destroy_generic(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
852 {
853         int err;
854
855         if (IS_ERR(eq))
856                 return -EINVAL;
857
858         err = destroy_async_eq(dev, eq);
859         if (err)
860                 goto out;
861
862         kvfree(eq);
863 out:
864         return err;
865 }
866 EXPORT_SYMBOL(mlx5_eq_destroy_generic);
867
868 struct mlx5_eqe *mlx5_eq_get_eqe(struct mlx5_eq *eq, u32 cc)
869 {
870         u32 ci = eq->cons_index + cc;
871         struct mlx5_eqe *eqe;
872
873         eqe = get_eqe(eq, ci & (eq->nent - 1));
874         eqe = ((eqe->owner & 1) ^ !!(ci & eq->nent)) ? NULL : eqe;
875         /* Make sure we read EQ entry contents after we've
876          * checked the ownership bit.
877          */
878         if (eqe)
879                 dma_rmb();
880
881         return eqe;
882 }
883 EXPORT_SYMBOL(mlx5_eq_get_eqe);
884
885 void mlx5_eq_update_ci(struct mlx5_eq *eq, u32 cc, bool arm)
886 {
887         __be32 __iomem *addr = eq->doorbell + (arm ? 0 : 2);
888         u32 val;
889
890         eq->cons_index += cc;
891         val = (eq->cons_index & 0xffffff) | (eq->eqn << 24);
892
893         __raw_writel((__force u32)cpu_to_be32(val), addr);
894         /* We still want ordering, just not swabbing, so add a barrier */
895         mb();
896 }
897 EXPORT_SYMBOL(mlx5_eq_update_ci);
898
899 /* Completion EQs */
900
901 static int set_comp_irq_affinity_hint(struct mlx5_core_dev *mdev, int i)
902 {
903         struct mlx5_priv *priv  = &mdev->priv;
904         int vecidx = MLX5_EQ_VEC_COMP_BASE + i;
905         int irq = pci_irq_vector(mdev->pdev, vecidx);
906         struct mlx5_irq_info *irq_info = &priv->eq_table->irq_info[vecidx];
907
908         if (!zalloc_cpumask_var(&irq_info->mask, GFP_KERNEL)) {
909                 mlx5_core_warn(mdev, "zalloc_cpumask_var failed");
910                 return -ENOMEM;
911         }
912
913         cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
914                         irq_info->mask);
915
916         if (IS_ENABLED(CONFIG_SMP) &&
917             irq_set_affinity_hint(irq, irq_info->mask))
918                 mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq);
919
920         return 0;
921 }
922
923 static void clear_comp_irq_affinity_hint(struct mlx5_core_dev *mdev, int i)
924 {
925         int vecidx = MLX5_EQ_VEC_COMP_BASE + i;
926         struct mlx5_priv *priv  = &mdev->priv;
927         int irq = pci_irq_vector(mdev->pdev, vecidx);
928         struct mlx5_irq_info *irq_info = &priv->eq_table->irq_info[vecidx];
929
930         irq_set_affinity_hint(irq, NULL);
931         free_cpumask_var(irq_info->mask);
932 }
933
934 static int set_comp_irq_affinity_hints(struct mlx5_core_dev *mdev)
935 {
936         int err;
937         int i;
938
939         for (i = 0; i < mdev->priv.eq_table->num_comp_vectors; i++) {
940                 err = set_comp_irq_affinity_hint(mdev, i);
941                 if (err)
942                         goto err_out;
943         }
944
945         return 0;
946
947 err_out:
948         for (i--; i >= 0; i--)
949                 clear_comp_irq_affinity_hint(mdev, i);
950
951         return err;
952 }
953
954 static void clear_comp_irqs_affinity_hints(struct mlx5_core_dev *mdev)
955 {
956         int i;
957
958         for (i = 0; i < mdev->priv.eq_table->num_comp_vectors; i++)
959                 clear_comp_irq_affinity_hint(mdev, i);
960 }
961
962 static void destroy_comp_eqs(struct mlx5_core_dev *dev)
963 {
964         struct mlx5_eq_table *table = dev->priv.eq_table;
965         struct mlx5_eq_comp *eq, *n;
966
967         clear_comp_irqs_affinity_hints(dev);
968
969 #ifdef CONFIG_RFS_ACCEL
970         if (table->rmap) {
971                 free_irq_cpu_rmap(table->rmap);
972                 table->rmap = NULL;
973         }
974 #endif
975         list_for_each_entry_safe(eq, n, &table->comp_eqs_list, list) {
976                 list_del(&eq->list);
977                 if (destroy_unmap_eq(dev, &eq->core))
978                         mlx5_core_warn(dev, "failed to destroy comp EQ 0x%x\n",
979                                        eq->core.eqn);
980                 tasklet_disable(&eq->tasklet_ctx.task);
981                 kfree(eq);
982         }
983 }
984
985 static int create_comp_eqs(struct mlx5_core_dev *dev)
986 {
987         struct mlx5_eq_table *table = dev->priv.eq_table;
988         char name[MLX5_MAX_IRQ_NAME];
989         struct mlx5_eq_comp *eq;
990         int ncomp_vec;
991         int nent;
992         int err;
993         int i;
994
995         INIT_LIST_HEAD(&table->comp_eqs_list);
996         ncomp_vec = table->num_comp_vectors;
997         nent = MLX5_COMP_EQ_SIZE;
998 #ifdef CONFIG_RFS_ACCEL
999         table->rmap = alloc_irq_cpu_rmap(ncomp_vec);
1000         if (!table->rmap)
1001                 return -ENOMEM;
1002 #endif
1003         for (i = 0; i < ncomp_vec; i++) {
1004                 int vecidx = i + MLX5_EQ_VEC_COMP_BASE;
1005                 struct mlx5_eq_param param = {};
1006
1007                 eq = kzalloc(sizeof(*eq), GFP_KERNEL);
1008                 if (!eq) {
1009                         err = -ENOMEM;
1010                         goto clean;
1011                 }
1012
1013                 INIT_LIST_HEAD(&eq->tasklet_ctx.list);
1014                 INIT_LIST_HEAD(&eq->tasklet_ctx.process_list);
1015                 spin_lock_init(&eq->tasklet_ctx.lock);
1016                 tasklet_init(&eq->tasklet_ctx.task, mlx5_cq_tasklet_cb,
1017                              (unsigned long)&eq->tasklet_ctx);
1018
1019 #ifdef CONFIG_RFS_ACCEL
1020                 irq_cpu_rmap_add(table->rmap, pci_irq_vector(dev->pdev, vecidx));
1021 #endif
1022                 snprintf(name, MLX5_MAX_IRQ_NAME, "mlx5_comp%d", i);
1023                 param = (struct mlx5_eq_param) {
1024                         .index = vecidx,
1025                         .mask = 0,
1026                         .nent = nent,
1027                         .context = &eq->core,
1028                         .handler = mlx5_eq_comp_int
1029                 };
1030                 err = create_map_eq(dev, &eq->core, name, &param);
1031                 if (err) {
1032                         kfree(eq);
1033                         goto clean;
1034                 }
1035                 mlx5_core_dbg(dev, "allocated completion EQN %d\n", eq->core.eqn);
1036                 /* add tail, to keep the list ordered, for mlx5_vector2eqn to work */
1037                 list_add_tail(&eq->list, &table->comp_eqs_list);
1038         }
1039
1040         err = set_comp_irq_affinity_hints(dev);
1041         if (err) {
1042                 mlx5_core_err(dev, "Failed to alloc affinity hint cpumask\n");
1043                 goto clean;
1044         }
1045
1046         return 0;
1047
1048 clean:
1049         destroy_comp_eqs(dev);
1050         return err;
1051 }
1052
1053 int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
1054                     unsigned int *irqn)
1055 {
1056         struct mlx5_eq_table *table = dev->priv.eq_table;
1057         struct mlx5_eq_comp *eq, *n;
1058         int err = -ENOENT;
1059         int i = 0;
1060
1061         list_for_each_entry_safe(eq, n, &table->comp_eqs_list, list) {
1062                 if (i++ == vector) {
1063                         *eqn = eq->core.eqn;
1064                         *irqn = eq->core.irqn;
1065                         err = 0;
1066                         break;
1067                 }
1068         }
1069
1070         return err;
1071 }
1072 EXPORT_SYMBOL(mlx5_vector2eqn);
1073
1074 unsigned int mlx5_comp_vectors_count(struct mlx5_core_dev *dev)
1075 {
1076         return dev->priv.eq_table->num_comp_vectors;
1077 }
1078 EXPORT_SYMBOL(mlx5_comp_vectors_count);
1079
1080 struct cpumask *
1081 mlx5_comp_irq_get_affinity_mask(struct mlx5_core_dev *dev, int vector)
1082 {
1083         /* TODO: consider irq_get_affinity_mask(irq) */
1084         return dev->priv.eq_table->irq_info[vector + MLX5_EQ_VEC_COMP_BASE].mask;
1085 }
1086 EXPORT_SYMBOL(mlx5_comp_irq_get_affinity_mask);
1087
1088 struct cpu_rmap *mlx5_eq_table_get_rmap(struct mlx5_core_dev *dev)
1089 {
1090 #ifdef CONFIG_RFS_ACCEL
1091         return dev->priv.eq_table->rmap;
1092 #else
1093         return NULL;
1094 #endif
1095 }
1096
1097 struct mlx5_eq_comp *mlx5_eqn2comp_eq(struct mlx5_core_dev *dev, int eqn)
1098 {
1099         struct mlx5_eq_table *table = dev->priv.eq_table;
1100         struct mlx5_eq_comp *eq;
1101
1102         list_for_each_entry(eq, &table->comp_eqs_list, list) {
1103                 if (eq->core.eqn == eqn)
1104                         return eq;
1105         }
1106
1107         return ERR_PTR(-ENOENT);
1108 }
1109
1110 /* This function should only be called after mlx5_cmd_force_teardown_hca */
1111 void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev)
1112 {
1113         struct mlx5_eq_table *table = dev->priv.eq_table;
1114         int i, max_eqs;
1115
1116         clear_comp_irqs_affinity_hints(dev);
1117
1118 #ifdef CONFIG_RFS_ACCEL
1119         if (table->rmap) {
1120                 free_irq_cpu_rmap(table->rmap);
1121                 table->rmap = NULL;
1122         }
1123 #endif
1124
1125         mutex_lock(&table->lock); /* sync with create/destroy_async_eq */
1126         max_eqs = table->num_comp_vectors + MLX5_EQ_VEC_COMP_BASE;
1127         for (i = max_eqs - 1; i >= 0; i--) {
1128                 if (!table->irq_info[i].context)
1129                         continue;
1130                 free_irq(pci_irq_vector(dev->pdev, i), table->irq_info[i].context);
1131                 table->irq_info[i].context = NULL;
1132         }
1133         mutex_unlock(&table->lock);
1134         pci_free_irq_vectors(dev->pdev);
1135 }
1136
1137 static int alloc_irq_vectors(struct mlx5_core_dev *dev)
1138 {
1139         struct mlx5_priv *priv = &dev->priv;
1140         struct mlx5_eq_table *table = priv->eq_table;
1141         int num_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ?
1142                       MLX5_CAP_GEN(dev, max_num_eqs) :
1143                       1 << MLX5_CAP_GEN(dev, log_max_eq);
1144         int nvec;
1145         int err;
1146
1147         nvec = MLX5_CAP_GEN(dev, num_ports) * num_online_cpus() +
1148                MLX5_EQ_VEC_COMP_BASE;
1149         nvec = min_t(int, nvec, num_eqs);
1150         if (nvec <= MLX5_EQ_VEC_COMP_BASE)
1151                 return -ENOMEM;
1152
1153         table->irq_info = kcalloc(nvec, sizeof(*table->irq_info), GFP_KERNEL);
1154         if (!table->irq_info)
1155                 return -ENOMEM;
1156
1157         nvec = pci_alloc_irq_vectors(dev->pdev, MLX5_EQ_VEC_COMP_BASE + 1,
1158                                      nvec, PCI_IRQ_MSIX);
1159         if (nvec < 0) {
1160                 err = nvec;
1161                 goto err_free_irq_info;
1162         }
1163
1164         table->num_comp_vectors = nvec - MLX5_EQ_VEC_COMP_BASE;
1165
1166         return 0;
1167
1168 err_free_irq_info:
1169         kfree(table->irq_info);
1170         return err;
1171 }
1172
1173 static void free_irq_vectors(struct mlx5_core_dev *dev)
1174 {
1175         struct mlx5_priv *priv = &dev->priv;
1176
1177         pci_free_irq_vectors(dev->pdev);
1178         kfree(priv->eq_table->irq_info);
1179 }
1180
1181 int mlx5_eq_table_create(struct mlx5_core_dev *dev)
1182 {
1183         int err;
1184
1185         err = alloc_irq_vectors(dev);
1186         if (err) {
1187                 mlx5_core_err(dev, "alloc irq vectors failed\n");
1188                 return err;
1189         }
1190
1191         err = create_async_eqs(dev);
1192         if (err) {
1193                 mlx5_core_err(dev, "Failed to create async EQs\n");
1194                 goto err_async_eqs;
1195         }
1196
1197         err = create_comp_eqs(dev);
1198         if (err) {
1199                 mlx5_core_err(dev, "Failed to create completion EQs\n");
1200                 goto err_comp_eqs;
1201         }
1202
1203         return 0;
1204 err_comp_eqs:
1205         destroy_async_eqs(dev);
1206 err_async_eqs:
1207         free_irq_vectors(dev);
1208         return err;
1209 }
1210
1211 void mlx5_eq_table_destroy(struct mlx5_core_dev *dev)
1212 {
1213         destroy_comp_eqs(dev);
1214         destroy_async_eqs(dev);
1215         free_irq_vectors(dev);
1216 }
1217
1218 int mlx5_eq_notifier_register(struct mlx5_core_dev *dev, struct mlx5_nb *nb)
1219 {
1220         struct mlx5_eq_table *eqt = dev->priv.eq_table;
1221
1222         if (nb->event_type >= MLX5_EVENT_TYPE_MAX)
1223                 return -EINVAL;
1224
1225         return atomic_notifier_chain_register(&eqt->nh[nb->event_type], &nb->nb);
1226 }
1227
1228 int mlx5_eq_notifier_unregister(struct mlx5_core_dev *dev, struct mlx5_nb *nb)
1229 {
1230         struct mlx5_eq_table *eqt = dev->priv.eq_table;
1231
1232         if (nb->event_type >= MLX5_EVENT_TYPE_MAX)
1233                 return -EINVAL;
1234
1235         return atomic_notifier_chain_unregister(&eqt->nh[nb->event_type], &nb->nb);
1236 }