[MLTHCA] added polling mode support.
[mirror/winof/.git] / hw / mlx4 / kernel / bus / net / eq.c
1 /*
2  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
3  * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33
34 #include "mlx4.h"
35 #include "cmd.h"
36 #include "fw.h"
37 #include "eq.h"
38
39 /*
40  * Must be packed because start is 64 bits but only aligned to 32 bits.
41  */
42 struct mlx4_eq_context {
43         __be32                  flags;
44         u16                     reserved1[3];
45         __be16                  page_offset;
46         u8                      log_eq_size;
47         u8                      reserved2[4];
48         u8                      eq_period;
49         u8                      reserved3;
50         u8                      eq_max_count;
51         u8                      reserved4[3];
52         u8                      intr;
53         u8                      log_page_size;
54         u8                      reserved5[2];
55         u8                      mtt_base_addr_h;
56         __be32                  mtt_base_addr_l;
57         u32                     reserved6[2];
58         __be32                  consumer_index;
59         __be32                  producer_index;
60         u32                     reserved7[4];
61 };
62
63 #define MLX4_EQ_STATUS_OK          ( 0 << 28)
64 #define MLX4_EQ_STATUS_WRITE_FAIL  (10 << 28)
65 #define MLX4_EQ_OWNER_SW           ( 0 << 24)
66 #define MLX4_EQ_OWNER_HW           ( 1 << 24)
67 #define MLX4_EQ_FLAG_EC            ( 1 << 18)
68 #define MLX4_EQ_FLAG_OI            ( 1 << 17)
69 #define MLX4_EQ_STATE_ARMED        ( 9 <<  8)
70 #define MLX4_EQ_STATE_FIRED        (10 <<  8)
71 #define MLX4_EQ_STATE_ALWAYS_ARMED (11 <<  8)
72
73 #define MLX4_ASYNC_EVENT_MASK ((1ull << MLX4_EVENT_TYPE_PATH_MIG)           | \
74                                (1ull << MLX4_EVENT_TYPE_COMM_EST)           | \
75                                (1ull << MLX4_EVENT_TYPE_SQ_DRAINED)         | \
76                                (1ull << MLX4_EVENT_TYPE_CQ_ERROR)           | \
77                                (1ull << MLX4_EVENT_TYPE_WQ_CATAS_ERROR)     | \
78                                (1ull << MLX4_EVENT_TYPE_EEC_CATAS_ERROR)    | \
79                                (1ull << MLX4_EVENT_TYPE_PATH_MIG_FAILED)    | \
80                                (1ull << MLX4_EVENT_TYPE_WQ_INVAL_REQ_ERROR) | \
81                                (1ull << MLX4_EVENT_TYPE_WQ_ACCESS_ERROR)    | \
82                                (1ull << MLX4_EVENT_TYPE_PORT_CHANGE)        | \
83                                (1ull << MLX4_EVENT_TYPE_ECC_DETECT)         | \
84                                (1ull << MLX4_EVENT_TYPE_SRQ_CATAS_ERROR)    | \
85                                (1ull << MLX4_EVENT_TYPE_SRQ_QP_LAST_WQE)    | \
86                                (1ull << MLX4_EVENT_TYPE_SRQ_LIMIT)          | \
87                                (1ull << MLX4_EVENT_TYPE_CMD))
88
89 #pragma warning( disable : 4706)
90 static int mlx4_eq_int(struct mlx4_dev *dev, struct mlx4_eq *eq)
91 {
92         struct mlx4_eqe *eqe;
93         int cqn;
94         int eqes_found = 0;
95         int set_ci = 0;
96         static const uint32_t cDpcMaxTime = 10000; //max time to spend in a while loop
97                 
98     uint64_t start = cl_get_time_stamp();
99
100         while ((eqe = next_eqe_sw(eq))) {
101                 /*
102                  * Make sure we read EQ entry contents after we've
103                  * checked the ownership bit.
104                  */
105                 rmb();
106
107                 switch (eqe->type) {
108                 case MLX4_EVENT_TYPE_COMP:
109                         cqn = be32_to_cpu(eqe->event.comp.cqn) & 0xffffff;
110                         mlx4_cq_completion(dev, cqn);
111                         break;
112
113                 case MLX4_EVENT_TYPE_PATH_MIG:
114                 case MLX4_EVENT_TYPE_COMM_EST:
115                 case MLX4_EVENT_TYPE_SQ_DRAINED:
116                 case MLX4_EVENT_TYPE_SRQ_QP_LAST_WQE:
117                 case MLX4_EVENT_TYPE_WQ_CATAS_ERROR:
118                 case MLX4_EVENT_TYPE_PATH_MIG_FAILED:
119                 case MLX4_EVENT_TYPE_WQ_INVAL_REQ_ERROR:
120                 case MLX4_EVENT_TYPE_WQ_ACCESS_ERROR:
121                         mlx4_qp_event(dev, be32_to_cpu(eqe->event.qp.qpn) & 0xffffff,
122                                       eqe->type);
123                         break;
124
125                 case MLX4_EVENT_TYPE_SRQ_LIMIT:
126                 case MLX4_EVENT_TYPE_SRQ_CATAS_ERROR:
127                         mlx4_srq_event(dev, be32_to_cpu(eqe->event.srq.srqn) & 0xffffff,
128                                       eqe->type);
129                         break;
130
131                 case MLX4_EVENT_TYPE_CMD:
132                         mlx4_cmd_event(dev,
133                                        be16_to_cpu(eqe->event.cmd.token),
134                                        eqe->event.cmd.status,
135                                        be64_to_cpu(eqe->event.cmd.out_param));
136                         break;
137
138                 case MLX4_EVENT_TYPE_PORT_CHANGE:
139                         mlx4_dispatch_event(dev, eqe->type, eqe->subtype,
140                                             be32_to_cpu(eqe->event.port_change.port) >> 28);
141                         break;
142
143                 case MLX4_EVENT_TYPE_CQ_ERROR:
144                         mlx4_warn(dev, "CQ %s on CQN %06x\n",
145                                   eqe->event.cq_err.syndrome == 1 ?
146                                   "overrun" : "access violation",
147                                   be32_to_cpu(eqe->event.cq_err.cqn) & 0xffffff);
148                         mlx4_cq_event(dev, be32_to_cpu(eqe->event.cq_err.cqn),
149                                       eqe->type);
150                         break;
151
152                 case MLX4_EVENT_TYPE_EQ_OVERFLOW:
153                         mlx4_warn(dev, "EQ overrun on EQN %d\n", eq->eqn);
154                         break;
155
156                 case MLX4_EVENT_TYPE_EEC_CATAS_ERROR:
157                 case MLX4_EVENT_TYPE_ECC_DETECT:
158                 default:
159                         mlx4_warn(dev, "Unhandled event %02x(%02x) on EQ %d at index %u\n",
160                                   eqe->type, eqe->subtype, eq->eqn, eq->cons_index);
161                         
162                         break;
163                 };
164
165                 ++eq->cons_index;
166                 eqes_found = 1;
167                 ++set_ci;
168
169                 /*
170                  * The HCA will think the queue has overflowed if we
171                  * don't tell it we've been processing events.  We
172                  * create our EQs with MLX4_NUM_SPARE_EQE extra
173                  * entries, so we must update our consumer index at
174                  * least that often.
175                  */
176                 if (unlikely(set_ci >= MLX4_NUM_SPARE_EQE)) {
177                         /*
178                          * Conditional on hca_type is OK here because
179                          * this is a rare case, not the fast path.
180                          */
181                         eq_set_ci(eq, 0);
182                         set_ci = 0;
183                 }
184                 
185                 if (cl_get_time_stamp() - start > cDpcMaxTime ) {
186                         break; //allow other DPCs as well
187                 }
188         }
189
190         eq_set_ci(eq, 1);
191
192         return eqes_found;
193 }
194 #pragma warning(disable:4706)
195
196 static void mlx4_dpc( PRKDPC dpc, 
197         PVOID ctx, PVOID arg1, PVOID arg2 )
198 {
199         struct mlx4_eq *eq  = ctx;
200
201         UNREFERENCED_PARAMETER(dpc);
202         UNREFERENCED_PARAMETER(arg1);
203         UNREFERENCED_PARAMETER(arg2);
204
205         spin_lock_dpc(&eq->lock);
206         mlx4_eq_int(eq->dev, eq);
207         spin_unlock_dpc(&eq->lock);
208 }
209
210 static BOOLEAN mlx4_interrupt(
211         IN struct _KINTERRUPT *Interrupt,
212         IN PVOID ServiceContext
213         )
214 {
215         struct mlx4_dev *dev = ServiceContext;
216         struct mlx4_priv *priv = mlx4_priv(dev);
217         int work = 0;
218         int i;
219
220         UNUSED_PARAM(Interrupt);
221         
222         writel(priv->eq_table.clr_mask, priv->eq_table.clr_int);
223
224         for (i = 0; i < MLX4_NUM_EQ; ++i) {
225                 if ( next_eqe_sw(&priv->eq_table.eq[i]) ) {
226                         work = 1;
227                         /* another interrupt may happen instantly after writel above.
228                         If it comes to another processor, mlx4_interrupt will be called
229                         and try to schedule the same DPC. So we protect KeInsertQueueDpc
230                         from that race */
231                         
232                         while(InterlockedCompareExchange(&dev->pdev->dpc_lock, 1, 0));
233                         
234                         KeInsertQueueDpc(&priv->eq_table.eq[i].dpc, NULL, NULL);
235                         InterlockedCompareExchange(&dev->pdev->dpc_lock, 0, 1);
236                 } else {
237                         /* re-arm the EQ for a case when interrupt comes before EQE
238                         and we didn't scheduled the DPC */
239                         eq_set_ci(&priv->eq_table.eq[i], 1);
240                 }
241         }
242
243         for (i = MLX4_NUM_EQ; i <= priv->eq_table.max_extra_eqs; ++i) {
244                 if (priv->eq_table.eq[i].isr) {
245                         int ret = 0;
246                         if ( next_eqe_sw(&priv->eq_table.eq[i]) ) {
247                                 ret = priv->eq_table.eq[i].isr(priv->eq_table.eq[i].ctx);
248                                 work |= ret;
249                         } else {
250                                 eq_set_ci(&priv->eq_table.eq[i], 1);
251                         }
252                 }
253         }
254
255         return (BOOLEAN)work;
256 }
257
258 #if 1//WORKAROUND_POLL_EQ
259
260 BOOLEAN
261 IsrSynchronizeRoutine(
262         IN PVOID  SynchronizeContext
263         )
264 {
265         struct mlx4_dev *dev = (struct mlx4_dev *)SynchronizeContext;
266     
267         mlx4_interrupt(dev->pdev->int_obj,dev);
268     
269         return TRUE;
270 }
271
272
273 VOID eq_polling_thread(void *ctx) 
274 {
275 #define POLLING_INTERVAL_MS     50
276         NTSTATUS status;
277         struct mlx4_priv *priv = (struct mlx4_priv *)ctx;
278         PVOID wait_objects[2];
279         LARGE_INTEGER  wait_time;
280
281         wait_objects[0] = &priv->eq_table.thread_stop_event;
282         wait_objects[1] = &priv->eq_table.thread_start_event;
283
284         for(;;){
285
286                 /* before start polling */
287                 DbgPrint("Before polling.\n");
288                 for (;;) {
289                         status = KeWaitForMultipleObjects( 2, wait_objects, 
290                                                                                            WaitAny, Executive, KernelMode, FALSE, NULL, NULL );
291
292                         if ( status == STATUS_WAIT_0 ){/* thread stopped */
293                                 DbgPrint("Signaled to stop polling.\n");
294                                 break;          
295                         }
296
297                         /* start polling */
298                         if ( status == STATUS_WAIT_1 ){
299                                 DbgPrint("Signaled to start polling.\n");
300                                 break;          
301                         }
302
303                 }
304
305                 if(priv->eq_table.bTerminated) break;
306                 if ( status == STATUS_WAIT_0 ) continue;/* thread stopped, wait for start again */
307
308                 /* polling */
309                 DbgPrint("Start polling.\n");
310                 wait_time.QuadPart = -(int64_t)(((uint64_t)POLLING_INTERVAL_MS) * 10000);
311                 for (;;) {
312                         //mlx4_interrupt( NULL, &priv->dev );
313                         KeSynchronizeExecution(priv->dev.pdev->int_obj, IsrSynchronizeRoutine, &priv->dev);
314
315                         status = KeWaitForSingleObject( &priv->eq_table.thread_stop_event, 
316                                                                                         Executive, KernelMode, FALSE, &wait_time );
317                         if ( status == STATUS_SUCCESS ) {
318                                 //KeClearEvent(&priv->eq_table.thread_stop_event);
319                                 DbgPrint("Signaled to stop polling while in polling mode.\n");
320                                 break;          /* thread stopped */
321                         }
322                 }
323
324                 if(priv->eq_table.bTerminated) break;
325         }
326
327         DbgPrint("Polling thread terminated.\n");
328         PsTerminateSystemThread(STATUS_SUCCESS);
329
330 }
331
332
333 void mlx4_poll_eq(struct ib_device *device, BOOLEAN bStart)
334 {
335         LONG signalled=0;
336         struct mlx4_priv *priv = mlx4_priv(device->dma_device);
337
338         if(bStart){
339                 /* signal start of polling */
340                 signalled = KeSetEvent(         
341                         &priv->eq_table.thread_start_event, IO_NO_INCREMENT, FALSE );
342         }else{
343                 /* signal end of polling */
344                 signalled = KeSetEvent(         
345                         &priv->eq_table.thread_stop_event, IO_NO_INCREMENT, FALSE );
346         }
347
348 }
349
350 #endif
351
352
353 #ifdef CONFIG_PCI_MSI
354
355 /* not ported yet */
356 static irqreturn_t mlx4_msi_x_interrupt(int irq, void *eq_ptr)
357 {
358         struct mlx4_eq  *eq  = eq_ptr;
359         struct mlx4_dev *dev = eq->dev;
360
361         mlx4_eq_int(dev, eq);
362
363         /* MSI-X vectors always belong to us */
364         return IRQ_HANDLED;
365 }
366
367 #endif
368
369 static int mlx4_MAP_EQ(struct mlx4_dev *dev, u64 event_mask, int unmap,
370                         int eq_num)
371 {
372         return mlx4_cmd(dev, event_mask, (unmap << 31) | eq_num,
373                         0, MLX4_CMD_MAP_EQ, MLX4_CMD_TIME_CLASS_B);
374 }
375
376 static int mlx4_SW2HW_EQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
377                          int eq_num)
378 {
379         return mlx4_cmd(dev, mailbox->dma.da, eq_num, 0, MLX4_CMD_SW2HW_EQ,
380                         MLX4_CMD_TIME_CLASS_A);
381 }
382
383 static int mlx4_HW2SW_EQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
384                          int eq_num)
385 {
386         return mlx4_cmd_box(dev, 0, mailbox->dma.da, eq_num, 0, MLX4_CMD_HW2SW_EQ,
387                             MLX4_CMD_TIME_CLASS_A);
388 }
389
390 static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq)
391 {
392         struct mlx4_priv *priv = mlx4_priv(dev);
393         int index;
394
395         index = eq->eqn / 4 - dev->caps.reserved_eqs / 4;
396
397         if (!priv->eq_table.uar_map[index]) {
398                 priv->eq_table.uar_map[index] =
399                         ioremap(pci_resource_start(dev->pdev, 2) +
400                                 ((eq->eqn / 4) << PAGE_SHIFT),
401                                 PAGE_SIZE);
402                 if (!priv->eq_table.uar_map[index]) {
403                         mlx4_err(dev, "Couldn't map EQ doorbell for EQN 0x%06x\n",
404                                  eq->eqn);
405                         return NULL;
406                 }
407         }
408
409         return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4);
410 }
411
412 static int mlx4_create_eq(struct mlx4_dev *dev, int nent,
413                           u8 intr, struct mlx4_eq *eq)
414 {
415         struct mlx4_priv *priv = mlx4_priv(dev);
416         struct mlx4_cmd_mailbox *mailbox;
417         struct mlx4_eq_context *eq_context;
418         int npages;
419         u64 *dma_list = NULL;
420         dma_addr_t t;
421         u64 mtt_addr;
422         int err = -ENOMEM;
423         int i;
424
425         eq->dev   = dev;
426         eq->nent  = roundup_pow_of_two(max(nent, 2));
427         npages = (int)(NEXT_PAGE_ALIGN(eq->nent * MLX4_EQ_ENTRY_SIZE) / PAGE_SIZE);
428
429         eq->page_list = kmalloc(npages * sizeof *eq->page_list,
430                                 GFP_KERNEL);
431         if (!eq->page_list)
432                 goto err_out;
433
434         for (i = 0; i < npages; ++i)
435                 eq->page_list[i].buf = NULL;
436
437         dma_list = kmalloc(npages * sizeof *dma_list, GFP_KERNEL);
438         if (!dma_list)
439                 goto err_out_free;
440
441         mailbox = mlx4_alloc_cmd_mailbox(dev);
442         if (IS_ERR(mailbox))
443                 goto err_out_free;
444         eq_context = (struct mlx4_eq_context *)mailbox->buf;
445
446         for (i = 0; i < npages; ++i) {
447                 eq->page_list[i].buf = dma_alloc_coherent(&dev->pdev->dev,
448                                                           PAGE_SIZE, &t, GFP_KERNEL);
449                 if (!eq->page_list[i].buf)
450                         goto err_out_free_pages;
451
452                 dma_list[i] = t.da;
453                 eq->page_list[i].map = t;
454
455                 memset(eq->page_list[i].buf, 0, PAGE_SIZE);
456         }
457
458         eq->eqn = mlx4_bitmap_alloc(&priv->eq_table.bitmap);
459         if (eq->eqn == -1)
460                 goto err_out_free_pages;
461
462         eq->doorbell = mlx4_get_eq_uar(dev, eq);
463         if (!eq->doorbell) {
464                 err = -ENOMEM;
465                 goto err_out_free_eq;
466         }
467
468         err = mlx4_mtt_init(dev, npages, PAGE_SHIFT, &eq->mtt);
469         if (err)
470                 goto err_out_free_eq;
471
472         err = mlx4_write_mtt(dev, &eq->mtt, 0, npages, dma_list);
473         if (err)
474                 goto err_out_free_mtt;
475
476         memset(eq_context, 0, sizeof *eq_context);
477         eq_context->flags         = cpu_to_be32(MLX4_EQ_STATUS_OK   |
478                                                 MLX4_EQ_STATE_ARMED);
479         eq_context->log_eq_size   = (u8)ilog2(eq->nent);
480         eq_context->intr          = intr;
481         eq_context->log_page_size = PAGE_SHIFT - MLX4_ICM_PAGE_SHIFT;
482
483         mtt_addr = mlx4_mtt_addr(dev, &eq->mtt);
484         eq_context->mtt_base_addr_h = (u8)(mtt_addr >> 32);
485         eq_context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff);
486
487         err = mlx4_SW2HW_EQ(dev, mailbox, eq->eqn);
488         if (err) {
489                 mlx4_warn(dev, "SW2HW_EQ failed (%d)\n", err);
490                 goto err_out_free_mtt;
491         }
492
493         kfree(dma_list);
494         mlx4_free_cmd_mailbox(dev, mailbox);
495
496         eq->cons_index = 0;
497
498         return err;
499
500 err_out_free_mtt:
501         mlx4_mtt_cleanup(dev, &eq->mtt);
502
503 err_out_free_eq:
504         mlx4_bitmap_free(&priv->eq_table.bitmap, eq->eqn);
505
506 err_out_free_pages:
507         for (i = 0; i < npages; ++i)
508                 if (eq->page_list[i].buf)
509                         dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
510                                           eq->page_list[i].buf,
511                                           eq->page_list[i].map);
512
513         mlx4_free_cmd_mailbox(dev, mailbox);
514
515 err_out_free:
516         kfree(eq->page_list);
517         kfree(dma_list);
518
519 err_out:
520         return err;
521 }
522
523 static void mlx4_free_eq(struct mlx4_dev *dev,
524                          struct mlx4_eq *eq)
525 {
526         struct mlx4_priv *priv = mlx4_priv(dev);
527         struct mlx4_cmd_mailbox *mailbox;
528         int err;
529         int npages = (int)(NEXT_PAGE_ALIGN(MLX4_EQ_ENTRY_SIZE * eq->nent) / PAGE_SIZE);
530         int i;
531
532         mailbox = mlx4_alloc_cmd_mailbox(dev);
533         if (IS_ERR(mailbox)) 
534                 mailbox = NULL;
535         else {
536                 err = mlx4_HW2SW_EQ(dev, mailbox, eq->eqn);
537                 if (err)
538                         mlx4_warn(dev, "HW2SW_EQ failed (%d)\n", err);
539         }
540
541 #if 0
542         {
543                 mlx4_dbg(dev, "Dumping EQ context %02x:\n", eq->eqn);
544                 for (i = 0; i < sizeof (struct mlx4_eq_context) / 4; ++i) {
545                         if (i % 4 == 0)
546                                 printk("[%02x] ", i * 4);
547                         printk(" %08x", be32_to_cpup(mailbox->buf + i * 4));
548                         if ((i + 1) % 4 == 0)
549                                 printk("\n");
550                 }
551         }
552 #endif  
553
554         mlx4_mtt_cleanup(dev, &eq->mtt);
555         for (i = 0; i < npages; ++i)
556                 pci_free_consistent(dev->pdev, PAGE_SIZE,
557                                     eq->page_list[i].buf,
558                                     eq->page_list[i].map);
559
560         kfree(eq->page_list);
561         mlx4_bitmap_free(&priv->eq_table.bitmap, eq->eqn);
562         mlx4_free_cmd_mailbox(dev, mailbox);
563 }
564
565 static void mlx4_free_irqs(struct mlx4_dev *dev)
566 {
567         struct mlx4_eq_table *eq_table = &mlx4_priv(dev)->eq_table;
568
569         if (eq_table->have_irq)
570                 free_irq(dev->pdev->int_obj);
571
572 #ifdef CONFIG_PCI_MSI
573         {
574                 int i;
575                 for (i = 0; i < MLX4_NUM_EQ; ++i)
576                         if (eq_table->eq[i].have_irq)
577                                 free_irq(eq_table->eq[i].irq, eq_table->eq + i);
578         }
579 #endif          
580 }
581
582 static int mlx4_map_clr_int(struct mlx4_dev *dev)
583 {
584         struct mlx4_priv *priv = mlx4_priv(dev);
585
586         priv->clr_base = ioremap(pci_resource_start(dev->pdev, priv->fw.clr_int_bar) +
587                                  priv->fw.clr_int_base, MLX4_CLR_INT_SIZE);
588         if (!priv->clr_base) {
589                 mlx4_err(dev, "Couldn't map interrupt clear register, aborting.\n");
590                 return -ENOMEM;
591         }
592
593         return 0;
594 }
595
596 static void mlx4_unmap_clr_int(struct mlx4_dev *dev)
597 {
598         struct mlx4_priv *priv = mlx4_priv(dev);
599
600         iounmap(priv->clr_base, MLX4_CLR_INT_SIZE);
601 }
602
603 int mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt)
604 {
605         struct mlx4_priv *priv = mlx4_priv(dev);
606         int ret;
607
608         /*
609          * We assume that mapping one page is enough for the whole EQ
610          * context table.  This is fine with all current HCAs, because
611          * we only use 32 EQs and each EQ uses 64 bytes of context
612          * memory, or 1 KB total.
613          */
614         priv->eq_table.icm_virt = icm_virt;
615         priv->eq_table.icm_page = alloc_page(dev->pdev, GFP_HIGHUSER);
616         if (!priv->eq_table.icm_page.da)
617                 return -ENOMEM;
618         priv->eq_table.icm_dma  = pci_map_page(dev->pdev, priv->eq_table.icm_page, 0,
619                                                PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
620         if (pci_dma_mapping_error(priv->eq_table.icm_dma)) {
621                 __free_page(dev->pdev, priv->eq_table.icm_page);
622                 return -ENOMEM;
623         }
624
625         ret = mlx4_MAP_ICM_page(dev, priv->eq_table.icm_dma.da, icm_virt);
626         if (ret) {
627                 pci_unmap_page(dev->pdev, priv->eq_table.icm_dma, PAGE_SIZE,
628                                PCI_DMA_BIDIRECTIONAL);
629                 __free_page(dev->pdev, priv->eq_table.icm_page);
630         }
631         mlx4_dbg(dev,"mlx4_MAP_ICM_page: dma %#I64x, icm_virt %#I64x\n", priv->eq_table.icm_dma.da, icm_virt);
632
633         return ret;
634 }
635
636 void mlx4_unmap_eq_icm(struct mlx4_dev *dev)
637 {
638         struct mlx4_priv *priv = mlx4_priv(dev);
639
640         mlx4_UNMAP_ICM(dev, priv->eq_table.icm_virt, 1);
641         pci_unmap_page(dev->pdev, priv->eq_table.icm_dma, PAGE_SIZE,
642                        PCI_DMA_BIDIRECTIONAL);
643         __free_page(dev->pdev, priv->eq_table.icm_page);
644 }
645
646 int mlx4_init_eq_table(struct mlx4_dev *dev)
647 {
648         struct mlx4_priv *priv = mlx4_priv(dev);
649         int err;
650         int i;
651
652         err = mlx4_bitmap_init(&priv->eq_table.bitmap, dev->caps.num_eqs,
653                                dev->caps.num_eqs - 1, dev->caps.reserved_eqs);
654         if (err)
655                 return err;
656
657         for (i = 0; i < ARRAY_SIZE(priv->eq_table.uar_map); ++i)
658                 priv->eq_table.uar_map[i] = NULL;
659
660         err = mlx4_map_clr_int(dev);
661         if (err)
662                 goto err_out_free;
663
664         priv->eq_table.clr_mask =
665                 swab32(1 << (priv->eq_table.inta_pin & 31));
666         priv->eq_table.clr_int  = priv->clr_base +
667                 (priv->eq_table.inta_pin < 32 ? 4 : 0);
668
669         err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE,
670                              (dev->flags & MLX4_FLAG_MSI_X) ? MLX4_EQ_COMP : 0,
671                              &priv->eq_table.eq[MLX4_EQ_COMP]);
672         if (err)
673                 goto err_out_unmap;
674
675         err = mlx4_create_eq(dev, MLX4_NUM_ASYNC_EQE + MLX4_NUM_SPARE_EQE,
676                              (dev->flags & MLX4_FLAG_MSI_X) ? MLX4_EQ_ASYNC : 0,
677                              &priv->eq_table.eq[MLX4_EQ_ASYNC]);
678         if (err)
679                 goto err_out_comp;
680
681 #ifdef CONFIG_PCI_MSI
682         if (dev->flags & MLX4_FLAG_MSI_X) {
683                 static const char *eq_name[] = {
684                         [MLX4_EQ_COMP]  = DRV_NAME " (comp)",
685                         [MLX4_EQ_ASYNC] = DRV_NAME " (async)"
686                 };
687
688 #ifdef USE_WDM_INTERRUPTS
689
690                         for (i = 0; i < MLX4_NUM_EQ; ++i) {
691                                 err = request_irq( dev, 
692                                         dev->pdev->int_info.u.Interrupt.Vector,
693                                         mlx4_interrupt, dev, 
694                                         mlx4_dpc, mlx4_msi_x_interrupt,
695                                         &dev->pdev->int_obj );
696                                 if (err)
697                                         goto err_out_async;
698
699                                 err = request_irq(priv->eq_table.eq[i].irq,
700                                                   mlx4_msi_x_interrupt,
701                                                   priv->eq_table.eq + i, eq_name[i], );
702                                 if (err)
703                                         goto err_out_async;
704                         
705                                 priv->eq_table.eq[i].have_irq = 1;
706                         }
707
708 #else
709                         #error MSI support is not implemented for WDF model
710 #endif          
711
712         } else 
713 #endif
714         {
715 #ifdef USE_WDM_INTERRUPTS
716         err = request_irq( dev, 
717                 dev->pdev->int_info.u.Interrupt.Vector,
718                 mlx4_interrupt, dev, 
719                 mlx4_dpc, NULL,
720                 &dev->pdev->int_obj );
721         if (err)
722                 goto err_out_async;
723 #else
724                 dev->pdev->dpc_lock = 0;
725                 for (i = 0; i < MLX4_NUM_EQ; ++i) {
726                         struct mlx4_eq * eq = &priv->eq_table.eq[i];
727                         spin_lock_init( &eq->lock );    
728                         eq->isr = mlx4_interrupt;
729                         eq->ctx = dev;
730                         KeInitializeDpc( &eq->dpc, mlx4_dpc, eq);
731                         eq->eq_ix = i;
732                 }
733 #endif          
734                 priv->eq_table.have_irq = 1;
735         }
736
737         err = mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0,
738                           priv->eq_table.eq[MLX4_EQ_ASYNC].eqn);
739         if (err)
740                 mlx4_warn(dev, "MAP_EQ for async EQ %d failed (%d)\n",
741                            priv->eq_table.eq[MLX4_EQ_ASYNC].eqn, err);
742
743         for (i = 0; i < MLX4_NUM_EQ; ++i)
744                 eq_set_ci(&priv->eq_table.eq[i], 1);
745
746
747 #if 1//WORKAROUND_POLL_EQ
748         { /* Create a thread for polling EQs in case of missing interrupts from the card  */
749                 NTSTATUS status;
750                 OBJECT_ATTRIBUTES       attr;
751                 HANDLE  handle;
752
753                 KeInitializeEvent(&priv->eq_table.thread_start_event, SynchronizationEvent, FALSE);
754                 KeInitializeEvent(&priv->eq_table.thread_stop_event, SynchronizationEvent, FALSE);
755                 priv->eq_table.bTerminated = FALSE;
756                 priv->eq_table.threadObject = NULL;
757                 InitializeObjectAttributes( &attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );
758                 status = PsCreateSystemThread( &handle, 
759                         THREAD_ALL_ACCESS, &attr, NULL, NULL, eq_polling_thread, priv );
760                 if (NT_SUCCESS(status)) {
761                         status = ObReferenceObjectByHandle(
762                                 handle,
763                                 THREAD_ALL_ACCESS,
764                                 NULL,
765                                 KernelMode,
766                                 &priv->eq_table.threadObject,
767                                 NULL
768                                 );
769
770                         ASSERT(status == STATUS_SUCCESS); //
771
772                         status = ZwClose(handle);
773
774                         ASSERT(NT_SUCCESS(status)); // Should always succeed
775
776                 }
777         }
778 #endif
779
780         return 0;
781
782 #ifdef USE_WDM_INTERRUPTS
783 err_out_async:
784         mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_ASYNC]);
785 #endif
786
787 err_out_comp:
788         mlx4_free_eq(dev, &priv->eq_table.eq[MLX4_EQ_COMP]);
789
790 err_out_unmap:
791         mlx4_unmap_clr_int(dev);
792         mlx4_free_irqs(dev);
793
794 err_out_free:
795         mlx4_bitmap_cleanup(&priv->eq_table.bitmap);
796         return err;
797 }
798
799
800 int mlx4_add_eq(struct mlx4_dev *dev, int nent,
801                           u8 intr, PISR_FUNC func, PVOID func_context ,
802                           u8* p_eq_num, struct mlx4_eq ** p_eq)
803 {
804         struct mlx4_priv *priv = mlx4_priv(dev);
805         int err;
806         u8 i, new_eq = 0;
807
808     UNREFERENCED_PARAMETER(intr);
809         
810         if ( mlx4_is_barred(dev) )
811                 return -EFAULT;
812         
813         for (i = MLX4_NUM_EQ; i < MLX4_NUM_EQ + MLX4_MAX_EXTRA_EQS ; i++) {
814                 if(priv->eq_table.eq[MLX4_NUM_EQ].isr == NULL) {
815                         new_eq = i;
816                         break;
817                 }
818         }
819         if (new_eq == 0)
820                 return -ENOMEM;
821
822         err = mlx4_create_eq(dev, nent,
823                              (dev->flags & MLX4_FLAG_MSI_X) ? MLX4_EQ_COMP : 0,
824                              &priv->eq_table.eq[new_eq]);
825         if (err)
826                 return err;
827
828         *p_eq = &priv->eq_table.eq[new_eq ];
829         *p_eq_num = new_eq;
830         priv->eq_table.eq[new_eq].isr = func;
831         priv->eq_table.eq[new_eq].ctx = func_context;
832         priv->eq_table.max_extra_eqs = max(priv->eq_table.max_extra_eqs, new_eq);
833         return 0;
834 }
835
836 void mlx4_remove_eq(struct mlx4_dev *dev, u8 eq_num)
837 {
838         struct mlx4_priv *priv = mlx4_priv(dev);
839         int err;
840         struct mlx4_eq_table *eq_table = &mlx4_priv(dev)->eq_table;
841
842         priv->eq_table.eq[eq_num].isr = NULL;
843         priv->eq_table.eq[eq_num].ctx = NULL;
844
845         if (priv->eq_table.max_extra_eqs == eq_num)
846                 priv->eq_table.max_extra_eqs--;
847
848         mlx4_free_eq(dev, &priv->eq_table.eq[eq_num]);
849
850
851         if (eq_table->have_irq) {
852                 free_irq(dev->pdev->int_obj);
853
854
855                 err = request_irq( dev, 
856                         dev->pdev->int_info.u.Interrupt.Vector,
857                         mlx4_interrupt, dev, 
858                         mlx4_dpc, NULL,
859                         &dev->pdev->int_obj );
860                 // BUGBUG: how should the error be propogated ?
861         }
862 }
863
864 void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
865 {
866         struct mlx4_priv *priv = mlx4_priv(dev);
867         int i;
868
869 #if 1//WORKAROUND_POLL_EQ
870         /* stop the EQ polling thread */
871         if (priv->eq_table.threadObject) { 
872                 #define WAIT_TIME_MS    3000
873                 NTSTATUS status;
874                 LARGE_INTEGER  wait_time;
875                 LONG signalled;
876
877                 priv->eq_table.bTerminated = TRUE;
878
879                 /* signal polling stopped in case it is not */
880                 signalled = KeSetEvent(         
881                         &priv->eq_table.thread_stop_event, IO_NO_INCREMENT, FALSE );
882
883                 /* wait for completion of the thread */
884                 wait_time.QuadPart = -(int64_t)(((uint64_t)WAIT_TIME_MS) * 10000);
885                 status = KeWaitForSingleObject( priv->eq_table.threadObject,
886                         Executive, KernelMode, FALSE, &wait_time );
887                 ASSERT(status == STATUS_SUCCESS);
888
889                 ObDereferenceObject(priv->eq_table.threadObject);
890
891                 /* cleanup */
892                 priv->eq_table.threadObject = NULL;
893         }
894 #endif
895
896         mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 1,
897                     priv->eq_table.eq[MLX4_EQ_ASYNC].eqn);
898
899         mlx4_free_irqs(dev);
900
901         for (i = 0; i < MLX4_NUM_EQ; ++i)
902                 mlx4_free_eq(dev, &priv->eq_table.eq[i]);
903
904         mlx4_unmap_clr_int(dev);
905
906         for (i = 0; i < ARRAY_SIZE(priv->eq_table.uar_map); ++i)
907                 if (priv->eq_table.uar_map[i])
908                         iounmap(priv->eq_table.uar_map[i],PAGE_SIZE);
909
910         mlx4_bitmap_cleanup(&priv->eq_table.bitmap);
911 }