1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/kernel.h>
17#include <linux/types.h>
18#include <linux/errno.h>
19#include <linux/pci.h>
20#include <linux/device.h>
21#include <linux/workqueue.h>
22#include <linux/interrupt.h>
23#include <linux/slab.h>
24#include <linux/dma-mapping.h>
25#include <linux/log2.h>
26#include <asm/byteorder.h>
27#include <asm/barrier.h>
28
29#include "hinic_hw_csr.h"
30#include "hinic_hw_if.h"
31#include "hinic_hw_eqs.h"
32
33#define HINIC_EQS_WQ_NAME "hinic_eqs"
34
35#define GET_EQ_NUM_PAGES(eq, pg_size) \
36 (ALIGN((eq)->q_len * (eq)->elem_size, pg_size) / (pg_size))
37
38#define GET_EQ_NUM_ELEMS_IN_PG(eq, pg_size) ((pg_size) / (eq)->elem_size)
39
40#define EQ_CONS_IDX_REG_ADDR(eq) (((eq)->type == HINIC_AEQ) ? \
41 HINIC_CSR_AEQ_CONS_IDX_ADDR((eq)->q_id) : \
42 HINIC_CSR_CEQ_CONS_IDX_ADDR((eq)->q_id))
43
44#define EQ_PROD_IDX_REG_ADDR(eq) (((eq)->type == HINIC_AEQ) ? \
45 HINIC_CSR_AEQ_PROD_IDX_ADDR((eq)->q_id) : \
46 HINIC_CSR_CEQ_PROD_IDX_ADDR((eq)->q_id))
47
48#define EQ_HI_PHYS_ADDR_REG(eq, pg_num) (((eq)->type == HINIC_AEQ) ? \
49 HINIC_CSR_AEQ_HI_PHYS_ADDR_REG((eq)->q_id, pg_num) : \
50 HINIC_CSR_CEQ_HI_PHYS_ADDR_REG((eq)->q_id, pg_num))
51
52#define EQ_LO_PHYS_ADDR_REG(eq, pg_num) (((eq)->type == HINIC_AEQ) ? \
53 HINIC_CSR_AEQ_LO_PHYS_ADDR_REG((eq)->q_id, pg_num) : \
54 HINIC_CSR_CEQ_LO_PHYS_ADDR_REG((eq)->q_id, pg_num))
55
56#define GET_EQ_ELEMENT(eq, idx) \
57 ((eq)->virt_addr[(idx) / (eq)->num_elem_in_pg] + \
58 (((idx) & ((eq)->num_elem_in_pg - 1)) * (eq)->elem_size))
59
60#define GET_AEQ_ELEM(eq, idx) ((struct hinic_aeq_elem *) \
61 GET_EQ_ELEMENT(eq, idx))
62
63#define GET_CEQ_ELEM(eq, idx) ((u32 *) \
64 GET_EQ_ELEMENT(eq, idx))
65
66#define GET_CURR_AEQ_ELEM(eq) GET_AEQ_ELEM(eq, (eq)->cons_idx)
67
68#define GET_CURR_CEQ_ELEM(eq) GET_CEQ_ELEM(eq, (eq)->cons_idx)
69
70#define PAGE_IN_4K(page_size) ((page_size) >> 12)
71#define EQ_SET_HW_PAGE_SIZE_VAL(eq) (ilog2(PAGE_IN_4K((eq)->page_size)))
72
73#define ELEMENT_SIZE_IN_32B(eq) (((eq)->elem_size) >> 5)
74#define EQ_SET_HW_ELEM_SIZE_VAL(eq) (ilog2(ELEMENT_SIZE_IN_32B(eq)))
75
76#define EQ_MAX_PAGES 8
77
78#define CEQE_TYPE_SHIFT 23
79#define CEQE_TYPE_MASK 0x7
80
81#define CEQE_TYPE(ceqe) (((ceqe) >> CEQE_TYPE_SHIFT) & \
82 CEQE_TYPE_MASK)
83
84#define CEQE_DATA_MASK 0x3FFFFFF
85#define CEQE_DATA(ceqe) ((ceqe) & CEQE_DATA_MASK)
86
87#define aeq_to_aeqs(eq) \
88 container_of((eq) - (eq)->q_id, struct hinic_aeqs, aeq[0])
89
90#define ceq_to_ceqs(eq) \
91 container_of((eq) - (eq)->q_id, struct hinic_ceqs, ceq[0])
92
93#define work_to_aeq_work(work) \
94 container_of(work, struct hinic_eq_work, work)
95
96#define DMA_ATTR_AEQ_DEFAULT 0
97#define DMA_ATTR_CEQ_DEFAULT 0
98
99
100#define THRESH_CEQ_DEFAULT 0
101
102enum eq_int_mode {
103 EQ_INT_MODE_ARMED,
104 EQ_INT_MODE_ALWAYS
105};
106
107enum eq_arm_state {
108 EQ_NOT_ARMED,
109 EQ_ARMED
110};
111
112
113
114
115
116
117
118
119void hinic_aeq_register_hw_cb(struct hinic_aeqs *aeqs,
120 enum hinic_aeq_type event, void *handle,
121 void (*hwe_handler)(void *handle, void *data,
122 u8 size))
123{
124 struct hinic_hw_event_cb *hwe_cb = &aeqs->hwe_cb[event];
125
126 hwe_cb->hwe_handler = hwe_handler;
127 hwe_cb->handle = handle;
128 hwe_cb->hwe_state = HINIC_EQE_ENABLED;
129}
130
131
132
133
134
135
136void hinic_aeq_unregister_hw_cb(struct hinic_aeqs *aeqs,
137 enum hinic_aeq_type event)
138{
139 struct hinic_hw_event_cb *hwe_cb = &aeqs->hwe_cb[event];
140
141 hwe_cb->hwe_state &= ~HINIC_EQE_ENABLED;
142
143 while (hwe_cb->hwe_state & HINIC_EQE_RUNNING)
144 schedule();
145
146 hwe_cb->hwe_handler = NULL;
147}
148
149
150
151
152
153
154
155
156void hinic_ceq_register_cb(struct hinic_ceqs *ceqs,
157 enum hinic_ceq_type event, void *handle,
158 void (*handler)(void *handle, u32 ceqe_data))
159{
160 struct hinic_ceq_cb *ceq_cb = &ceqs->ceq_cb[event];
161
162 ceq_cb->handler = handler;
163 ceq_cb->handle = handle;
164 ceq_cb->ceqe_state = HINIC_EQE_ENABLED;
165}
166
167
168
169
170
171
172void hinic_ceq_unregister_cb(struct hinic_ceqs *ceqs,
173 enum hinic_ceq_type event)
174{
175 struct hinic_ceq_cb *ceq_cb = &ceqs->ceq_cb[event];
176
177 ceq_cb->ceqe_state &= ~HINIC_EQE_ENABLED;
178
179 while (ceq_cb->ceqe_state & HINIC_EQE_RUNNING)
180 schedule();
181
182 ceq_cb->handler = NULL;
183}
184
185static u8 eq_cons_idx_checksum_set(u32 val)
186{
187 u8 checksum = 0;
188 int idx;
189
190 for (idx = 0; idx < 32; idx += 4)
191 checksum ^= ((val >> idx) & 0xF);
192
193 return (checksum & 0xF);
194}
195
196
197
198
199
200static void eq_update_ci(struct hinic_eq *eq)
201{
202 u32 val, addr = EQ_CONS_IDX_REG_ADDR(eq);
203
204
205 val = hinic_hwif_read_reg(eq->hwif, addr);
206
207 val = HINIC_EQ_CI_CLEAR(val, IDX) &
208 HINIC_EQ_CI_CLEAR(val, WRAPPED) &
209 HINIC_EQ_CI_CLEAR(val, INT_ARMED) &
210 HINIC_EQ_CI_CLEAR(val, XOR_CHKSUM);
211
212 val |= HINIC_EQ_CI_SET(eq->cons_idx, IDX) |
213 HINIC_EQ_CI_SET(eq->wrapped, WRAPPED) |
214 HINIC_EQ_CI_SET(EQ_ARMED, INT_ARMED);
215
216 val |= HINIC_EQ_CI_SET(eq_cons_idx_checksum_set(val), XOR_CHKSUM);
217
218 hinic_hwif_write_reg(eq->hwif, addr, val);
219}
220
221
222
223
224
225static void aeq_irq_handler(struct hinic_eq *eq)
226{
227 struct hinic_aeqs *aeqs = aeq_to_aeqs(eq);
228 struct hinic_hwif *hwif = aeqs->hwif;
229 struct pci_dev *pdev = hwif->pdev;
230 struct hinic_aeq_elem *aeqe_curr;
231 struct hinic_hw_event_cb *hwe_cb;
232 enum hinic_aeq_type event;
233 unsigned long eqe_state;
234 u32 aeqe_desc;
235 int i, size;
236
237 for (i = 0; i < eq->q_len; i++) {
238 aeqe_curr = GET_CURR_AEQ_ELEM(eq);
239
240
241 aeqe_desc = be32_to_cpu(aeqe_curr->desc);
242
243
244 if (HINIC_EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) == eq->wrapped)
245 break;
246
247 event = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, TYPE);
248 if (event >= HINIC_MAX_AEQ_EVENTS) {
249 dev_err(&pdev->dev, "Unknown AEQ Event %d\n", event);
250 return;
251 }
252
253 if (!HINIC_EQ_ELEM_DESC_GET(aeqe_desc, SRC)) {
254 hwe_cb = &aeqs->hwe_cb[event];
255
256 size = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, SIZE);
257
258 eqe_state = cmpxchg(&hwe_cb->hwe_state,
259 HINIC_EQE_ENABLED,
260 HINIC_EQE_ENABLED |
261 HINIC_EQE_RUNNING);
262 if ((eqe_state == HINIC_EQE_ENABLED) &&
263 (hwe_cb->hwe_handler))
264 hwe_cb->hwe_handler(hwe_cb->handle,
265 aeqe_curr->data, size);
266 else
267 dev_err(&pdev->dev, "Unhandled AEQ Event %d\n",
268 event);
269
270 hwe_cb->hwe_state &= ~HINIC_EQE_RUNNING;
271 }
272
273 eq->cons_idx++;
274
275 if (eq->cons_idx == eq->q_len) {
276 eq->cons_idx = 0;
277 eq->wrapped = !eq->wrapped;
278 }
279 }
280}
281
282
283
284
285
286
287static void ceq_event_handler(struct hinic_ceqs *ceqs, u32 ceqe)
288{
289 struct hinic_hwif *hwif = ceqs->hwif;
290 struct pci_dev *pdev = hwif->pdev;
291 struct hinic_ceq_cb *ceq_cb;
292 enum hinic_ceq_type event;
293 unsigned long eqe_state;
294
295 event = CEQE_TYPE(ceqe);
296 if (event >= HINIC_MAX_CEQ_EVENTS) {
297 dev_err(&pdev->dev, "Unknown CEQ event, event = %d\n", event);
298 return;
299 }
300
301 ceq_cb = &ceqs->ceq_cb[event];
302
303 eqe_state = cmpxchg(&ceq_cb->ceqe_state,
304 HINIC_EQE_ENABLED,
305 HINIC_EQE_ENABLED | HINIC_EQE_RUNNING);
306
307 if ((eqe_state == HINIC_EQE_ENABLED) && (ceq_cb->handler))
308 ceq_cb->handler(ceq_cb->handle, CEQE_DATA(ceqe));
309 else
310 dev_err(&pdev->dev, "Unhandled CEQ Event %d\n", event);
311
312 ceq_cb->ceqe_state &= ~HINIC_EQE_RUNNING;
313}
314
315
316
317
318
319static void ceq_irq_handler(struct hinic_eq *eq)
320{
321 struct hinic_ceqs *ceqs = ceq_to_ceqs(eq);
322 u32 ceqe;
323 int i;
324
325 for (i = 0; i < eq->q_len; i++) {
326 ceqe = *(GET_CURR_CEQ_ELEM(eq));
327
328
329 ceqe = be32_to_cpu(ceqe);
330
331
332 if (HINIC_EQ_ELEM_DESC_GET(ceqe, WRAPPED) == eq->wrapped)
333 break;
334
335 ceq_event_handler(ceqs, ceqe);
336
337 eq->cons_idx++;
338
339 if (eq->cons_idx == eq->q_len) {
340 eq->cons_idx = 0;
341 eq->wrapped = !eq->wrapped;
342 }
343 }
344}
345
346
347
348
349
350static void eq_irq_handler(void *data)
351{
352 struct hinic_eq *eq = data;
353
354 if (eq->type == HINIC_AEQ)
355 aeq_irq_handler(eq);
356 else if (eq->type == HINIC_CEQ)
357 ceq_irq_handler(eq);
358
359 eq_update_ci(eq);
360}
361
362
363
364
365
366static void eq_irq_work(struct work_struct *work)
367{
368 struct hinic_eq_work *aeq_work = work_to_aeq_work(work);
369 struct hinic_eq *aeq;
370
371 aeq = aeq_work->data;
372 eq_irq_handler(aeq);
373}
374
375
376
377
378
379static void ceq_tasklet(unsigned long ceq_data)
380{
381 struct hinic_eq *ceq = (struct hinic_eq *)ceq_data;
382
383 eq_irq_handler(ceq);
384}
385
386
387
388
389
390
391static irqreturn_t aeq_interrupt(int irq, void *data)
392{
393 struct hinic_eq_work *aeq_work;
394 struct hinic_eq *aeq = data;
395 struct hinic_aeqs *aeqs;
396
397
398 hinic_msix_attr_cnt_clear(aeq->hwif, aeq->msix_entry.entry);
399
400 aeq_work = &aeq->aeq_work;
401 aeq_work->data = aeq;
402
403 aeqs = aeq_to_aeqs(aeq);
404 queue_work(aeqs->workq, &aeq_work->work);
405
406 return IRQ_HANDLED;
407}
408
409
410
411
412
413
414static irqreturn_t ceq_interrupt(int irq, void *data)
415{
416 struct hinic_eq *ceq = data;
417
418
419 hinic_msix_attr_cnt_clear(ceq->hwif, ceq->msix_entry.entry);
420
421 tasklet_schedule(&ceq->ceq_tasklet);
422
423 return IRQ_HANDLED;
424}
425
426static void set_ctrl0(struct hinic_eq *eq)
427{
428 struct msix_entry *msix_entry = &eq->msix_entry;
429 enum hinic_eq_type type = eq->type;
430 u32 addr, val, ctrl0;
431
432 if (type == HINIC_AEQ) {
433
434 addr = HINIC_CSR_AEQ_CTRL_0_ADDR(eq->q_id);
435
436 val = hinic_hwif_read_reg(eq->hwif, addr);
437
438 val = HINIC_AEQ_CTRL_0_CLEAR(val, INT_IDX) &
439 HINIC_AEQ_CTRL_0_CLEAR(val, DMA_ATTR) &
440 HINIC_AEQ_CTRL_0_CLEAR(val, PCI_INTF_IDX) &
441 HINIC_AEQ_CTRL_0_CLEAR(val, INT_MODE);
442
443 ctrl0 = HINIC_AEQ_CTRL_0_SET(msix_entry->entry, INT_IDX) |
444 HINIC_AEQ_CTRL_0_SET(DMA_ATTR_AEQ_DEFAULT, DMA_ATTR) |
445 HINIC_AEQ_CTRL_0_SET(HINIC_HWIF_PCI_INTF(eq->hwif),
446 PCI_INTF_IDX) |
447 HINIC_AEQ_CTRL_0_SET(EQ_INT_MODE_ARMED, INT_MODE);
448
449 val |= ctrl0;
450
451 hinic_hwif_write_reg(eq->hwif, addr, val);
452 } else if (type == HINIC_CEQ) {
453
454 addr = HINIC_CSR_CEQ_CTRL_0_ADDR(eq->q_id);
455
456 val = hinic_hwif_read_reg(eq->hwif, addr);
457
458 val = HINIC_CEQ_CTRL_0_CLEAR(val, INTR_IDX) &
459 HINIC_CEQ_CTRL_0_CLEAR(val, DMA_ATTR) &
460 HINIC_CEQ_CTRL_0_CLEAR(val, KICK_THRESH) &
461 HINIC_CEQ_CTRL_0_CLEAR(val, PCI_INTF_IDX) &
462 HINIC_CEQ_CTRL_0_CLEAR(val, INTR_MODE);
463
464 ctrl0 = HINIC_CEQ_CTRL_0_SET(msix_entry->entry, INTR_IDX) |
465 HINIC_CEQ_CTRL_0_SET(DMA_ATTR_CEQ_DEFAULT, DMA_ATTR) |
466 HINIC_CEQ_CTRL_0_SET(THRESH_CEQ_DEFAULT, KICK_THRESH) |
467 HINIC_CEQ_CTRL_0_SET(HINIC_HWIF_PCI_INTF(eq->hwif),
468 PCI_INTF_IDX) |
469 HINIC_CEQ_CTRL_0_SET(EQ_INT_MODE_ARMED, INTR_MODE);
470
471 val |= ctrl0;
472
473 hinic_hwif_write_reg(eq->hwif, addr, val);
474 }
475}
476
477static void set_ctrl1(struct hinic_eq *eq)
478{
479 enum hinic_eq_type type = eq->type;
480 u32 page_size_val, elem_size;
481 u32 addr, val, ctrl1;
482
483 if (type == HINIC_AEQ) {
484
485 addr = HINIC_CSR_AEQ_CTRL_1_ADDR(eq->q_id);
486
487 page_size_val = EQ_SET_HW_PAGE_SIZE_VAL(eq);
488 elem_size = EQ_SET_HW_ELEM_SIZE_VAL(eq);
489
490 val = hinic_hwif_read_reg(eq->hwif, addr);
491
492 val = HINIC_AEQ_CTRL_1_CLEAR(val, LEN) &
493 HINIC_AEQ_CTRL_1_CLEAR(val, ELEM_SIZE) &
494 HINIC_AEQ_CTRL_1_CLEAR(val, PAGE_SIZE);
495
496 ctrl1 = HINIC_AEQ_CTRL_1_SET(eq->q_len, LEN) |
497 HINIC_AEQ_CTRL_1_SET(elem_size, ELEM_SIZE) |
498 HINIC_AEQ_CTRL_1_SET(page_size_val, PAGE_SIZE);
499
500 val |= ctrl1;
501
502 hinic_hwif_write_reg(eq->hwif, addr, val);
503 } else if (type == HINIC_CEQ) {
504
505 addr = HINIC_CSR_CEQ_CTRL_1_ADDR(eq->q_id);
506
507 page_size_val = EQ_SET_HW_PAGE_SIZE_VAL(eq);
508
509 val = hinic_hwif_read_reg(eq->hwif, addr);
510
511 val = HINIC_CEQ_CTRL_1_CLEAR(val, LEN) &
512 HINIC_CEQ_CTRL_1_CLEAR(val, PAGE_SIZE);
513
514 ctrl1 = HINIC_CEQ_CTRL_1_SET(eq->q_len, LEN) |
515 HINIC_CEQ_CTRL_1_SET(page_size_val, PAGE_SIZE);
516
517 val |= ctrl1;
518
519 hinic_hwif_write_reg(eq->hwif, addr, val);
520 }
521}
522
523
524
525
526
527static void set_eq_ctrls(struct hinic_eq *eq)
528{
529 set_ctrl0(eq);
530 set_ctrl1(eq);
531}
532
533
534
535
536
537
538static void aeq_elements_init(struct hinic_eq *eq, u32 init_val)
539{
540 struct hinic_aeq_elem *aeqe;
541 int i;
542
543 for (i = 0; i < eq->q_len; i++) {
544 aeqe = GET_AEQ_ELEM(eq, i);
545 aeqe->desc = cpu_to_be32(init_val);
546 }
547
548 wmb();
549}
550
551
552
553
554
555
556static void ceq_elements_init(struct hinic_eq *eq, u32 init_val)
557{
558 u32 *ceqe;
559 int i;
560
561 for (i = 0; i < eq->q_len; i++) {
562 ceqe = GET_CEQ_ELEM(eq, i);
563 *(ceqe) = cpu_to_be32(init_val);
564 }
565
566 wmb();
567}
568
569
570
571
572
573
574
575static int alloc_eq_pages(struct hinic_eq *eq)
576{
577 struct hinic_hwif *hwif = eq->hwif;
578 struct pci_dev *pdev = hwif->pdev;
579 u32 init_val, addr, val;
580 size_t addr_size;
581 int err, pg;
582
583 addr_size = eq->num_pages * sizeof(*eq->dma_addr);
584 eq->dma_addr = devm_kzalloc(&pdev->dev, addr_size, GFP_KERNEL);
585 if (!eq->dma_addr)
586 return -ENOMEM;
587
588 addr_size = eq->num_pages * sizeof(*eq->virt_addr);
589 eq->virt_addr = devm_kzalloc(&pdev->dev, addr_size, GFP_KERNEL);
590 if (!eq->virt_addr) {
591 err = -ENOMEM;
592 goto err_virt_addr_alloc;
593 }
594
595 for (pg = 0; pg < eq->num_pages; pg++) {
596 eq->virt_addr[pg] = dma_zalloc_coherent(&pdev->dev,
597 eq->page_size,
598 &eq->dma_addr[pg],
599 GFP_KERNEL);
600 if (!eq->virt_addr[pg]) {
601 err = -ENOMEM;
602 goto err_dma_alloc;
603 }
604
605 addr = EQ_HI_PHYS_ADDR_REG(eq, pg);
606 val = upper_32_bits(eq->dma_addr[pg]);
607
608 hinic_hwif_write_reg(hwif, addr, val);
609
610 addr = EQ_LO_PHYS_ADDR_REG(eq, pg);
611 val = lower_32_bits(eq->dma_addr[pg]);
612
613 hinic_hwif_write_reg(hwif, addr, val);
614 }
615
616 init_val = HINIC_EQ_ELEM_DESC_SET(eq->wrapped, WRAPPED);
617
618 if (eq->type == HINIC_AEQ)
619 aeq_elements_init(eq, init_val);
620 else if (eq->type == HINIC_CEQ)
621 ceq_elements_init(eq, init_val);
622
623 return 0;
624
625err_dma_alloc:
626 while (--pg >= 0)
627 dma_free_coherent(&pdev->dev, eq->page_size,
628 eq->virt_addr[pg],
629 eq->dma_addr[pg]);
630
631 devm_kfree(&pdev->dev, eq->virt_addr);
632
633err_virt_addr_alloc:
634 devm_kfree(&pdev->dev, eq->dma_addr);
635 return err;
636}
637
638
639
640
641
642static void free_eq_pages(struct hinic_eq *eq)
643{
644 struct hinic_hwif *hwif = eq->hwif;
645 struct pci_dev *pdev = hwif->pdev;
646 int pg;
647
648 for (pg = 0; pg < eq->num_pages; pg++)
649 dma_free_coherent(&pdev->dev, eq->page_size,
650 eq->virt_addr[pg],
651 eq->dma_addr[pg]);
652
653 devm_kfree(&pdev->dev, eq->virt_addr);
654 devm_kfree(&pdev->dev, eq->dma_addr);
655}
656
657
658
659
660
661
662
663
664
665
666
667
668
669static int init_eq(struct hinic_eq *eq, struct hinic_hwif *hwif,
670 enum hinic_eq_type type, int q_id, u32 q_len, u32 page_size,
671 struct msix_entry entry)
672{
673 struct pci_dev *pdev = hwif->pdev;
674 int err;
675
676 eq->hwif = hwif;
677 eq->type = type;
678 eq->q_id = q_id;
679 eq->q_len = q_len;
680 eq->page_size = page_size;
681
682
683 hinic_hwif_write_reg(eq->hwif, EQ_CONS_IDX_REG_ADDR(eq), 0);
684 hinic_hwif_write_reg(eq->hwif, EQ_PROD_IDX_REG_ADDR(eq), 0);
685
686 eq->cons_idx = 0;
687 eq->wrapped = 0;
688
689 if (type == HINIC_AEQ) {
690 eq->elem_size = HINIC_AEQE_SIZE;
691 } else if (type == HINIC_CEQ) {
692 eq->elem_size = HINIC_CEQE_SIZE;
693 } else {
694 dev_err(&pdev->dev, "Invalid EQ type\n");
695 return -EINVAL;
696 }
697
698 eq->num_pages = GET_EQ_NUM_PAGES(eq, page_size);
699 eq->num_elem_in_pg = GET_EQ_NUM_ELEMS_IN_PG(eq, page_size);
700
701 eq->msix_entry = entry;
702
703 if (eq->num_elem_in_pg & (eq->num_elem_in_pg - 1)) {
704 dev_err(&pdev->dev, "num elements in eq page != power of 2\n");
705 return -EINVAL;
706 }
707
708 if (eq->num_pages > EQ_MAX_PAGES) {
709 dev_err(&pdev->dev, "too many pages for eq\n");
710 return -EINVAL;
711 }
712
713 set_eq_ctrls(eq);
714 eq_update_ci(eq);
715
716 err = alloc_eq_pages(eq);
717 if (err) {
718 dev_err(&pdev->dev, "Failed to allocate pages for eq\n");
719 return err;
720 }
721
722 if (type == HINIC_AEQ) {
723 struct hinic_eq_work *aeq_work = &eq->aeq_work;
724
725 INIT_WORK(&aeq_work->work, eq_irq_work);
726 } else if (type == HINIC_CEQ) {
727 tasklet_init(&eq->ceq_tasklet, ceq_tasklet,
728 (unsigned long)eq);
729 }
730
731
732 hinic_msix_attr_set(eq->hwif, eq->msix_entry.entry,
733 HINIC_EQ_MSIX_PENDING_LIMIT_DEFAULT,
734 HINIC_EQ_MSIX_COALESC_TIMER_DEFAULT,
735 HINIC_EQ_MSIX_LLI_TIMER_DEFAULT,
736 HINIC_EQ_MSIX_LLI_CREDIT_LIMIT_DEFAULT,
737 HINIC_EQ_MSIX_RESEND_TIMER_DEFAULT);
738
739 if (type == HINIC_AEQ)
740 err = request_irq(entry.vector, aeq_interrupt, 0,
741 "hinic_aeq", eq);
742 else if (type == HINIC_CEQ)
743 err = request_irq(entry.vector, ceq_interrupt, 0,
744 "hinic_ceq", eq);
745
746 if (err) {
747 dev_err(&pdev->dev, "Failed to request irq for the EQ\n");
748 goto err_req_irq;
749 }
750
751 return 0;
752
753err_req_irq:
754 free_eq_pages(eq);
755 return err;
756}
757
758
759
760
761
762static void remove_eq(struct hinic_eq *eq)
763{
764 struct msix_entry *entry = &eq->msix_entry;
765
766 free_irq(entry->vector, eq);
767
768 if (eq->type == HINIC_AEQ) {
769 struct hinic_eq_work *aeq_work = &eq->aeq_work;
770
771 cancel_work_sync(&aeq_work->work);
772 } else if (eq->type == HINIC_CEQ) {
773 tasklet_kill(&eq->ceq_tasklet);
774 }
775
776 free_eq_pages(eq);
777}
778
779
780
781
782
783
784
785
786
787
788
789
790int hinic_aeqs_init(struct hinic_aeqs *aeqs, struct hinic_hwif *hwif,
791 int num_aeqs, u32 q_len, u32 page_size,
792 struct msix_entry *msix_entries)
793{
794 struct pci_dev *pdev = hwif->pdev;
795 int err, i, q_id;
796
797 aeqs->workq = create_singlethread_workqueue(HINIC_EQS_WQ_NAME);
798 if (!aeqs->workq)
799 return -ENOMEM;
800
801 aeqs->hwif = hwif;
802 aeqs->num_aeqs = num_aeqs;
803
804 for (q_id = 0; q_id < num_aeqs; q_id++) {
805 err = init_eq(&aeqs->aeq[q_id], hwif, HINIC_AEQ, q_id, q_len,
806 page_size, msix_entries[q_id]);
807 if (err) {
808 dev_err(&pdev->dev, "Failed to init aeq %d\n", q_id);
809 goto err_init_aeq;
810 }
811 }
812
813 return 0;
814
815err_init_aeq:
816 for (i = 0; i < q_id; i++)
817 remove_eq(&aeqs->aeq[i]);
818
819 destroy_workqueue(aeqs->workq);
820 return err;
821}
822
823
824
825
826
827void hinic_aeqs_free(struct hinic_aeqs *aeqs)
828{
829 int q_id;
830
831 for (q_id = 0; q_id < aeqs->num_aeqs ; q_id++)
832 remove_eq(&aeqs->aeq[q_id]);
833
834 destroy_workqueue(aeqs->workq);
835}
836
837
838
839
840
841
842
843
844
845
846
847
848int hinic_ceqs_init(struct hinic_ceqs *ceqs, struct hinic_hwif *hwif,
849 int num_ceqs, u32 q_len, u32 page_size,
850 struct msix_entry *msix_entries)
851{
852 struct pci_dev *pdev = hwif->pdev;
853 int i, q_id, err;
854
855 ceqs->hwif = hwif;
856 ceqs->num_ceqs = num_ceqs;
857
858 for (q_id = 0; q_id < num_ceqs; q_id++) {
859 err = init_eq(&ceqs->ceq[q_id], hwif, HINIC_CEQ, q_id, q_len,
860 page_size, msix_entries[q_id]);
861 if (err) {
862 dev_err(&pdev->dev, "Failed to init ceq %d\n", q_id);
863 goto err_init_ceq;
864 }
865 }
866
867 return 0;
868
869err_init_ceq:
870 for (i = 0; i < q_id; i++)
871 remove_eq(&ceqs->ceq[i]);
872
873 return err;
874}
875
876
877
878
879
880void hinic_ceqs_free(struct hinic_ceqs *ceqs)
881{
882 int q_id;
883
884 for (q_id = 0; q_id < ceqs->num_ceqs; q_id++)
885 remove_eq(&ceqs->ceq[q_id]);
886}
887