925b00f93b44d156904b79e49577326511fce38c
[people/xl0/gpxe.git] / src / drivers / net / mlx_ipoib / mt25218.c
1 /**************************************************************************
2 Etherboot -  BOOTP/TFTP Bootstrap Program
3 Skeleton NIC driver for Etherboot
4 ***************************************************************************/
5
6 /*
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2, or (at
10  * your option) any later version.
11  */
12
13 #include <errno.h>
14 #include <gpxe/pci.h>
15 #include <gpxe/malloc.h>
16 #include <gpxe/iobuf.h>
17 #include <gpxe/netdevice.h>
18 #include <gpxe/infiniband.h>
19
20 /* to get some global routines like printf */
21 #include "etherboot.h"
22 /* to get the interface to the body of the program */
23 #include "nic.h"
24
25 #include "mt25218_imp.c"
26
27 #include "arbel.h"
28
29
30 static const struct ib_gid arbel_no_gid = {
31         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }
32 };
33
34
35 #define MLX_RX_MAX_FILL NUM_IPOIB_RCV_WQES
36
37 struct mlx_nic {
38         /** Queue pair handle */
39         udqp_t ipoib_qph;
40         /** Broadcast Address Vector */
41         ud_av_t bcast_av;
42         /** Send completion queue */
43         cq_t snd_cqh;
44         /** Receive completion queue */
45         cq_t rcv_cqh;
46
47         /** RX fill level */
48         unsigned int rx_fill;
49 };
50
51
52 static struct io_buffer *static_ipoib_tx_ring[NUM_IPOIB_SND_WQES];
53 static struct io_buffer *static_ipoib_rx_ring[NUM_IPOIB_RCV_WQES];
54
55 static struct arbel static_arbel;
56 static struct arbel_completion_queue static_ipoib_send_cq;
57 static struct arbel_completion_queue static_ipoib_recv_cq;
58
59 static struct arbel_queue_pair static_ipoib_qp = {
60         .qp = {
61                 .send = {
62                         .qp = &static_ipoib_qp.qp,
63                         .is_send = 1,
64                         .cq = &static_ipoib_send_cq.cq,
65                         .num_wqes = NUM_IPOIB_SND_WQES,
66                         .iobufs = static_ipoib_tx_ring,
67                         .list = LIST_HEAD_INIT (static_ipoib_qp.qp.send.list),
68                 },
69                 .recv = {
70                         .qp = &static_ipoib_qp.qp,
71                         .is_send = 0,
72                         .cq = &static_ipoib_recv_cq.cq,
73                         .num_wqes = NUM_IPOIB_RCV_WQES,
74                         .iobufs = static_ipoib_rx_ring,
75                         .list = LIST_HEAD_INIT (static_ipoib_qp.qp.recv.list),
76                 },
77         },
78         .send = {
79                 .doorbell_idx = IPOIB_SND_QP_DB_IDX,
80         },
81         .recv = {
82                 .doorbell_idx = IPOIB_RCV_QP_DB_IDX,
83         },
84 };
85 static struct arbel_completion_queue static_ipoib_send_cq = {
86         .cq = {
87                 .cqn = 1234, /* Only used for debug messages */
88                 .num_cqes = NUM_IPOIB_SND_CQES,
89                 .work_queues = LIST_HEAD_INIT (static_ipoib_send_cq.cq.work_queues),
90         },
91         .doorbell_idx = IPOIB_SND_CQ_CI_DB_IDX,
92 };
93 static struct arbel_completion_queue static_ipoib_recv_cq = {
94         .cq = {
95                 .cqn = 2345, /* Only used for debug messages */
96                 .num_cqes = NUM_IPOIB_RCV_CQES,
97                 .work_queues = LIST_HEAD_INIT (static_ipoib_recv_cq.cq.work_queues),
98         },
99         .doorbell_idx = IPOIB_RCV_CQ_CI_DB_IDX,
100 };
101 static struct ib_device static_ibdev = {
102         .priv = &static_arbel,
103 };
104
105
106 /**
107  * Open network device
108  *
109  * @v netdev            Network device
110  * @ret rc              Return status code
111  */
112 static int mlx_open ( struct net_device *netdev ) {
113
114         ( void ) netdev;
115
116         return 0;
117 }
118
119 /**
120  * Close network device
121  *
122  * @v netdev            Network device
123  */
124 static void mlx_close ( struct net_device *netdev ) {
125
126         ( void ) netdev;
127
128 }
129
130 static int arbel_post_send ( struct ib_device *ibdev,
131                              struct ib_queue_pair *qp,
132                              struct ib_address_vector *av,
133                              struct io_buffer *iobuf );
134
135 static int mlx_transmit_direct ( struct net_device *netdev,
136                                  struct io_buffer *iobuf ) {
137         struct mlx_nic *mlx = netdev->priv;
138         int rc;
139
140         struct ud_av_st *bcast_av = mlx->bcast_av;
141         struct arbelprm_ud_address_vector *bav =
142                 ( struct arbelprm_ud_address_vector * ) &bcast_av->av;
143         struct ib_address_vector av = {
144                 .dest_qp = bcast_av->dest_qp,
145                 .qkey = bcast_av->qkey,
146                 .dlid = MLX_GET ( bav, rlid ),
147                 .rate = ( MLX_GET ( bav, max_stat_rate ) ? 1 : 4 ),
148                 .sl = MLX_GET ( bav, sl ),
149                 .gid_present = 1,
150         };
151         memcpy ( &av.gid, ( ( void * ) bav ) + 16, 16 );
152
153         rc = arbel_post_send ( &static_ibdev, &static_ipoib_qp.qp, &av, iobuf );
154
155         return rc;
156 }
157
158 static void arbel_poll_cq ( struct ib_device *ibdev,
159                             struct ib_completion_queue *cq,
160                             ib_completer_t complete_send,
161                             ib_completer_t complete_recv );
162
163 static void temp_complete_send ( struct ib_device *ibdev __unused,
164                                  struct ib_queue_pair *qp,
165                                  struct ib_completion *completion,
166                                  struct io_buffer *iobuf ) {
167         struct net_device *netdev = qp->priv;
168
169         DBG ( "Wahey! TX completion\n" );
170         netdev_tx_complete_err ( netdev, iobuf,
171                                  ( completion->syndrome ? -EIO : 0 ) );
172 }
173
174 static void temp_complete_recv ( struct ib_device *ibdev __unused,
175                                  struct ib_queue_pair *qp,
176                                  struct ib_completion *completion,
177                                  struct io_buffer *iobuf ) {
178         struct net_device *netdev = qp->priv;
179         struct mlx_nic *mlx = netdev->priv;
180
181         DBG ( "Yay! RX completion on %p len %zx:\n", iobuf, completion->len );
182         if ( completion->syndrome ) {
183                 netdev_rx_err ( netdev, iobuf, -EIO );
184         } else {
185                 iob_put ( iobuf, completion->len );
186                 iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
187                 netdev_rx ( netdev, iobuf );
188         }
189
190         mlx->rx_fill--;
191 }
192
193 static int arbel_post_recv ( struct ib_device *ibdev,
194                              struct ib_queue_pair *qp,
195                              struct io_buffer *iobuf );
196
197 static void mlx_refill_rx ( struct net_device *netdev ) {
198         struct mlx_nic *mlx = netdev->priv;
199         struct io_buffer *iobuf;
200         int rc;
201
202         while ( mlx->rx_fill < MLX_RX_MAX_FILL ) {
203                 iobuf = alloc_iob ( 2048 );
204                 if ( ! iobuf )
205                         break;
206                 DBG ( "Posting RX buffer %p:\n", iobuf );
207                 if ( ( rc = arbel_post_recv ( &static_ibdev,
208                                               &static_ipoib_qp.qp,
209                                               iobuf ) ) != 0 ) {
210                         free_iob ( iobuf );
211                         break;
212                 }
213                 mlx->rx_fill++;
214         }
215 }
216
217 /**
218  * Poll for completed and received packets
219  *
220  * @v netdev            Network device
221  */
222 static void mlx_poll ( struct net_device *netdev ) {
223         struct mlx_nic *mlx = netdev->priv;
224         int rc;
225
226         if ( ( rc = poll_error_buf() ) != 0 ) {
227                 DBG ( "poll_error_buf() failed: %s\n", strerror ( rc ) );
228                 return;
229         }
230
231         /* Drain event queue.  We can ignore events, since we're going
232          * to just poll all completion queues anyway.
233          */
234         if ( ( rc = drain_eq() ) != 0 ) {
235                 DBG ( "drain_eq() failed: %s\n", strerror ( rc ) );
236                 return;
237         }
238
239         /* Poll completion queues */
240         arbel_poll_cq ( &static_ibdev, &static_ipoib_send_cq.cq,
241                         temp_complete_send, temp_complete_recv );
242         arbel_poll_cq ( &static_ibdev, &static_ipoib_recv_cq.cq,
243                         temp_complete_send, temp_complete_recv );
244         //      mlx_poll_cq ( netdev, mlx->rcv_cqh, mlx_rx_complete );
245
246         mlx_refill_rx ( netdev );
247 }
248
249 /**
250  * Enable or disable interrupts
251  *
252  * @v netdev            Network device
253  * @v enable            Interrupts should be enabled
254  */
255 static void mlx_irq ( struct net_device *netdev, int enable ) {
256
257         ( void ) netdev;
258         ( void ) enable;
259
260 }
261
262 static struct net_device_operations mlx_operations = {
263         .open           = mlx_open,
264         .close          = mlx_close,
265         .transmit       = mlx_transmit_direct,
266         .poll           = mlx_poll,
267         .irq            = mlx_irq,
268 };
269
270
271
272
273 /**
274  * Allocate queue number
275  *
276  * @v q_inuse           Queue usage bitmask
277  * @v max_inuse         Maximum number of in-use queues
278  * @ret qn_offset       Free queue number offset, or negative error
279  */
280 static int arbel_alloc_qn_offset ( arbel_bitmask_t *q_inuse,
281                                    unsigned int max_inuse ) {
282         unsigned int qn_offset = 0;
283         arbel_bitmask_t mask = 1;
284
285         while ( qn_offset < max_inuse ) {
286                 if ( ( mask & *q_inuse ) == 0 ) {
287                         *q_inuse |= mask;
288                         return qn_offset;
289                 }
290                 qn_offset++;
291                 mask <<= 1;
292                 if ( ! mask ) {
293                         mask = 1;
294                         q_inuse++;
295                 }
296         }
297         return -ENFILE;
298 }
299
300 /**
301  * Free queue number
302  *
303  * @v q_inuse           Queue usage bitmask
304  * @v qn_offset         Queue number offset
305  */
306 static void arbel_free_qn_offset ( arbel_bitmask_t *q_inuse, int qn_offset ) {
307         arbel_bitmask_t mask;
308
309         mask = ( 1 << ( qn_offset % ( 8 * sizeof ( mask ) ) ) );
310         q_inuse += ( qn_offset / ( 8 * sizeof ( mask ) ) );
311         *q_inuse &= ~mask;
312 }
313
314 /***************************************************************************
315  *
316  * HCA commands
317  *
318  ***************************************************************************
319  */
320
321 /**
322  * Wait for Arbel command completion
323  *
324  * @v arbel             Arbel device
325  * @ret rc              Return status code
326  */
327 static int arbel_cmd_wait ( struct arbel *arbel,
328                             struct arbelprm_hca_command_register *hcr ) {
329         unsigned int wait;
330
331         for ( wait = ARBEL_HCR_MAX_WAIT_MS ; wait ; wait-- ) {
332                 hcr->u.dwords[6] =
333                         readl ( arbel->config + ARBEL_HCR_REG ( 6 ) );
334                 if ( MLX_GET ( hcr, go ) == 0 )
335                         return 0;
336                 mdelay ( 1 );
337         }
338         return -EBUSY;
339 }
340
341 /**
342  * Issue HCA command
343  *
344  * @v arbel             Arbel device
345  * @v command           Command opcode, flags and input/output lengths
346  * @v op_mod            Opcode modifier (0 if no modifier applicable)
347  * @v in                Input parameters
348  * @v in_mod            Input modifier (0 if no modifier applicable)
349  * @v out               Output parameters
350  * @ret rc              Return status code
351  */
352 static int arbel_cmd ( struct arbel *arbel, unsigned long command,
353                        unsigned int op_mod, const void *in,
354                        unsigned int in_mod, void *out ) {
355         struct arbelprm_hca_command_register hcr;
356         unsigned int opcode = ARBEL_HCR_OPCODE ( command );
357         size_t in_len = ARBEL_HCR_IN_LEN ( command );
358         size_t out_len = ARBEL_HCR_OUT_LEN ( command );
359         void *in_buffer;
360         void *out_buffer;
361         unsigned int status;
362         unsigned int i;
363         int rc;
364
365         DBGC ( arbel, "Arbel %p command %02x in %zx%s out %zx%s\n",
366                arbel, opcode, in_len,
367                ( ( command & ARBEL_HCR_IN_MBOX ) ? "(mbox)" : "" ), out_len,
368                ( ( command & ARBEL_HCR_OUT_MBOX ) ? "(mbox)" : "" ) );
369
370         /* Check that HCR is free */
371         if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
372                 DBGC ( arbel, "Arbel %p command interface locked\n", arbel );
373                 return rc;
374         }
375
376         /* Prepare HCR */
377         memset ( &hcr, 0, sizeof ( hcr ) );
378         in_buffer = &hcr.u.dwords[0];
379         if ( in_len && ( command & ARBEL_HCR_IN_MBOX ) ) {
380                 in_buffer = arbel->mailbox_in;
381                 MLX_FILL_1 ( &hcr, 1, in_param_l, virt_to_bus ( in_buffer ) );
382         }
383         memcpy ( in_buffer, in, in_len );
384         MLX_FILL_1 ( &hcr, 2, input_modifier, in_mod );
385         out_buffer = &hcr.u.dwords[3];
386         if ( out_len && ( command & ARBEL_HCR_OUT_MBOX ) ) {
387                 out_buffer = arbel->mailbox_out;
388                 MLX_FILL_1 ( &hcr, 4, out_param_l,
389                              virt_to_bus ( out_buffer ) );
390         }
391         MLX_FILL_3 ( &hcr, 6,
392                      opcode, opcode,
393                      opcode_modifier, op_mod,
394                      go, 1 );
395
396         /* Issue command */
397         for ( i = 0 ; i < ( sizeof ( hcr ) / sizeof ( hcr.u.dwords[0] ) ) ;
398               i++ ) {
399                 writel ( hcr.u.dwords[i],
400                          arbel->config + ARBEL_HCR_REG ( i ) );
401                 barrier();
402         }
403
404         /* Wait for command completion */
405         if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
406                 DBGC ( arbel, "Arbel %p timed out waiting for command:\n",
407                        arbel );
408                 DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
409                 return rc;
410         }
411
412         /* Check command status */
413         status = MLX_GET ( &hcr, status );
414         if ( status != 0 ) {
415                 DBGC ( arbel, "Arbel %p command failed with status %02x:\n",
416                        arbel, status );
417                 DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
418                 return -EIO;
419         }
420
421         /* Read output parameters, if any */
422         hcr.u.dwords[3] = readl ( arbel->config + ARBEL_HCR_REG ( 3 ) );
423         hcr.u.dwords[4] = readl ( arbel->config + ARBEL_HCR_REG ( 4 ) );
424         memcpy ( out, out_buffer, out_len );
425
426         return 0;
427 }
428
429 static inline int
430 arbel_cmd_query_dev_lim ( struct arbel *arbel,
431                           struct arbelprm_query_dev_lim *dev_lim ) {
432         return arbel_cmd ( arbel,
433                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_QUERY_DEV_LIM, 
434                                                1, sizeof ( *dev_lim ) ),
435                            0, NULL, 0, dev_lim );
436 }
437
438 static inline int
439 arbel_cmd_sw2hw_cq ( struct arbel *arbel, unsigned long cqn,
440                      const struct arbelprm_completion_queue_context *cqctx ) {
441         return arbel_cmd ( arbel,
442                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_SW2HW_CQ,
443                                               1, sizeof ( *cqctx ) ),
444                            0, cqctx, cqn, NULL );
445 }
446
447 /***************************************************************************
448  *
449  * Completion queue operations
450  *
451  ***************************************************************************
452  */
453
454 /**
455  * Create completion queue
456  *
457  * @v ibdev             Infiniband device
458  * @v 
459  */
460 static int arbel_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
461                              struct ib_completion_queue **new_cq ) {
462         struct arbel *arbel = ibdev->priv;
463         struct arbel_completion_queue *arbel_cq;
464         struct arbelprm_completion_queue_context cqctx;
465         int cqn_offset;
466         unsigned int cqn;
467         size_t cqe_size;
468         unsigned int i;
469         int rc;
470
471         /* Find a free completion queue number */
472         cqn_offset = arbel_alloc_qn_offset ( arbel->cq_inuse, ARBEL_MAX_CQS );
473         if ( cqn_offset < 0 ) {
474                 rc = cqn_offset;
475                 goto err_cqn_offset;
476         }
477         cqn = ( arbel->limits.reserved_cqs + cqn_offset );
478
479         /* Allocate control structures */
480         arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
481         if ( ! arbel_cq ) {
482                 rc = -ENOMEM;
483                 goto err_arbel_cq;
484         }
485         arbel_cq->cq.cqn = cqn;
486         arbel_cq->cq.num_cqes = num_cqes;
487         INIT_LIST_HEAD ( &arbel_cq->cq.work_queues );
488         arbel_cq->doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
489
490         /* Allocate completion queue itself */
491         cqe_size = ( num_cqes * sizeof ( arbel_cq->cqe[0] ) );
492         arbel_cq->cqe = malloc_dma ( cqe_size, sizeof ( arbel_cq->cqe[0] ) );
493         if ( ! arbel_cq->cqe ) {
494                 rc = -ENOMEM;
495                 goto err_cqe;
496         }
497         memset ( arbel_cq->cqe, 0, cqe_size );
498         for ( i = 0 ; i < num_cqes ; i++ ) {
499                 MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
500         }
501         barrier();
502
503         /* Initialise doorbell records */
504         // ...
505
506         /* Hand queue over to hardware */
507         memset ( &cqctx, 0, sizeof ( cqctx ) );
508         MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
509         MLX_FILL_1 ( &cqctx, 2, start_address_l,
510                      virt_to_bus ( arbel_cq->cqe ) );
511         ///     ....
512
513         if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cqn, &cqctx ) ) != 0 ) {
514                 // ...
515         }
516
517
518         // completion queue number
519         // doorbell index
520
521         *new_cq = &arbel_cq->cq;
522
523
524         return 0;
525
526  err_cqe:
527         free ( arbel_cq );
528  err_arbel_cq:
529         arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
530  err_cqn_offset:
531         return rc;
532 }
533
534
535 /***************************************************************************
536  *
537  * Work request operations
538  *
539  ***************************************************************************
540  */
541
542 /**
543  * Ring doorbell register in UAR
544  *
545  * @v arbel             Arbel device
546  * @v db_reg            Doorbell register structure
547  * @v offset            Address of doorbell
548  */
549 static void arbel_ring_doorbell ( struct arbel *arbel,
550                                   union arbelprm_doorbell_register *db_reg,
551                                   unsigned int offset ) {
552
553         DBG ( "arbel_ring_doorbell %08lx:%08lx to %lx\n",
554               db_reg->dword[0], db_reg->dword[1],
555               virt_to_phys ( arbel->uar + offset ) );
556
557         barrier();
558         writel ( db_reg->dword[0], ( arbel->uar + offset + 0 ) );
559         barrier();
560         writel ( db_reg->dword[1], ( arbel->uar + offset + 4 ) );
561 }
562
563 /**
564  * Post send work queue entry
565  *
566  * @v ibdev             Infiniband device
567  * @v qp                Queue pair
568  * @v av                Address vector
569  * @v iobuf             I/O buffer
570  * @ret rc              Return status code
571  */
572 static int arbel_post_send ( struct ib_device *ibdev,
573                              struct ib_queue_pair *qp,
574                              struct ib_address_vector *av,
575                              struct io_buffer *iobuf ) {
576         struct arbel *arbel = ibdev->priv;
577         struct arbel_queue_pair *arbel_qp
578                 = container_of ( qp, struct arbel_queue_pair, qp );
579         struct ib_work_queue *wq = &qp->send;
580         struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
581         struct arbelprm_ud_send_wqe *prev_wqe;
582         struct arbelprm_ud_send_wqe *wqe;
583         union arbelprm_doorbell_record *db_rec;
584         union arbelprm_doorbell_register db_reg;
585         const struct ib_gid *gid;
586         unsigned int wqe_idx_mask;
587         size_t nds;
588
589         /* Allocate work queue entry */
590         wqe_idx_mask = ( wq->num_wqes - 1 );
591         if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
592                 DBGC ( arbel, "Arbel %p send queue full", arbel );
593                 return -ENOBUFS;
594         }
595         wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
596         prev_wqe = &arbel_send_wq->wqe[(wq->next_idx - 1) & wqe_idx_mask].ud;
597         wqe = &arbel_send_wq->wqe[wq->next_idx & wqe_idx_mask].ud;
598
599         /* Construct work queue entry */
600         MLX_FILL_1 ( &wqe->next, 1, always1, 1 );
601         memset ( &wqe->ctrl, 0, sizeof ( wqe->ctrl ) );
602         MLX_FILL_1 ( &wqe->ctrl, 0, always1, 1 );
603         memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
604         MLX_FILL_2 ( &wqe->ud, 0,
605                      ud_address_vector.pd, GLOBAL_PD,
606                      ud_address_vector.port_number, PXE_IB_PORT );
607         MLX_FILL_2 ( &wqe->ud, 1,
608                      ud_address_vector.rlid, av->dlid,
609                      ud_address_vector.g, av->gid_present );
610         MLX_FILL_2 ( &wqe->ud, 2,
611                      ud_address_vector.max_stat_rate,
612                          ( ( av->rate >= 3 ) ? 0 : 1 ),
613                      ud_address_vector.msg, 3 );
614         MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
615         gid = ( av->gid_present ? &av->gid : &arbel_no_gid );
616         memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) );
617         MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->dest_qp );
618         MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
619         MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
620         MLX_FILL_1 ( &wqe->data[0], 3,
621                      local_address_l, virt_to_bus ( iobuf->data ) );
622
623         /* Update previous work queue entry's "next" field */
624         nds = ( ( offsetof ( typeof ( *wqe ), data ) +
625                   sizeof ( wqe->data[0] ) ) >> 4 );
626         MLX_SET ( &prev_wqe->next, nopcode, ARBEL_OPCODE_SEND );
627         MLX_FILL_3 ( &prev_wqe->next, 1,
628                      nds, nds,
629                      f, 1,
630                      always1, 1 );
631
632         /* Update doorbell record */
633         barrier();
634         db_rec = &arbel->db_rec[arbel_send_wq->doorbell_idx];
635         MLX_FILL_1 ( &db_rec->qp, 0,
636                      counter, ( ( wq->next_idx + 1 ) & 0xffff ) );
637
638         /* Ring doorbell register */
639         MLX_FILL_4 ( &db_reg.send, 0,
640                      nopcode, ARBEL_OPCODE_SEND,
641                      f, 1,
642                      wqe_counter, ( wq->next_idx & 0xffff ),
643                      wqe_cnt, 1 );
644         MLX_FILL_2 ( &db_reg.send, 1,
645                      nds, nds,
646                      qpn, qp->qpn );
647         arbel_ring_doorbell ( arbel, &db_reg, POST_SND_OFFSET );
648
649         /* Update work queue's index */
650         wq->next_idx++;
651
652         return 0;
653 }
654
655 /**
656  * Post receive work queue entry
657  *
658  * @v ibdev             Infiniband device
659  * @v qp                Queue pair
660  * @v iobuf             I/O buffer
661  * @ret rc              Return status code
662  */
663 static int arbel_post_recv ( struct ib_device *ibdev,
664                              struct ib_queue_pair *qp,
665                              struct io_buffer *iobuf ) {
666         struct arbel *arbel = ibdev->priv;
667         struct arbel_queue_pair *arbel_qp
668                 = container_of ( qp, struct arbel_queue_pair, qp );
669         struct ib_work_queue *wq = &qp->recv;
670         struct arbel_recv_work_queue *arbel_recv_wq = &arbel_qp->recv;
671         struct arbelprm_recv_wqe *wqe;
672         union arbelprm_doorbell_record *db_rec;
673         unsigned int wqe_idx_mask;
674
675         /* Allocate work queue entry */
676         wqe_idx_mask = ( wq->num_wqes - 1 );
677         if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
678                 DBGC ( arbel, "Arbel %p receive queue full", arbel );
679                 return -ENOBUFS;
680         }
681         wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
682         wqe = &arbel_recv_wq->wqe[wq->next_idx & wqe_idx_mask].recv;
683
684         /* Construct work queue entry */
685         MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
686         MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
687         MLX_FILL_1 ( &wqe->data[0], 3,
688                      local_address_l, virt_to_bus ( iobuf->data ) );
689
690         /* Update doorbell record */
691         barrier();
692         db_rec = &arbel->db_rec[arbel_recv_wq->doorbell_idx];
693         MLX_FILL_1 ( &db_rec->qp, 0,
694                      counter, ( ( wq->next_idx + 1 ) & 0xffff ) );      
695
696         /* Update work queue's index */
697         wq->next_idx++;
698
699         return 0;       
700 }
701
702 /**
703  * Handle completion
704  *
705  * @v ibdev             Infiniband device
706  * @v cq                Completion queue
707  * @v cqe               Hardware completion queue entry
708  * @v complete_send     Send completion handler
709  * @v complete_recv     Receive completion handler
710  * @ret rc              Return status code
711  */
712 static int arbel_complete ( struct ib_device *ibdev,
713                             struct ib_completion_queue *cq,
714                             union arbelprm_completion_entry *cqe,
715                             ib_completer_t complete_send,
716                             ib_completer_t complete_recv ) {
717         struct arbel *arbel = ibdev->priv;
718         struct ib_completion completion;
719         struct ib_work_queue *wq;
720         struct ib_queue_pair *qp;
721         struct arbel_queue_pair *arbel_qp;
722         struct arbel_send_work_queue *arbel_send_wq;
723         struct arbel_recv_work_queue *arbel_recv_wq;
724         struct io_buffer *iobuf;
725         ib_completer_t complete;
726         unsigned int opcode;
727         unsigned long qpn;
728         int is_send;
729         unsigned long wqe_adr;
730         unsigned int wqe_idx;
731         int rc = 0;
732
733         /* Parse completion */
734         memset ( &completion, 0, sizeof ( completion ) );
735         completion.len = MLX_GET ( &cqe->normal, byte_cnt );
736         qpn = MLX_GET ( &cqe->normal, my_qpn );
737         is_send = MLX_GET ( &cqe->normal, s );
738         wqe_adr = ( MLX_GET ( &cqe->normal, wqe_adr ) << 6 );
739         opcode = MLX_GET ( &cqe->normal, opcode );
740         if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) {
741                 /* "s" field is not valid for error opcodes */
742                 is_send = ( opcode == ARBEL_OPCODE_SEND_ERROR );
743                 completion.syndrome = MLX_GET ( &cqe->error, syndrome );
744                 DBGC ( arbel, "Arbel %p CPN %lx syndrome %x vendor %lx\n",
745                        arbel, cq->cqn, completion.syndrome,
746                        MLX_GET ( &cqe->error, vendor_code ) );
747                 rc = -EIO;
748                 /* Don't return immediately; propagate error to completer */
749         }
750
751         /* Identify work queue */
752         wq = ib_find_wq ( cq, qpn, is_send );
753         if ( ! wq ) {
754                 DBGC ( arbel, "Arbel %p CQN %lx unknown %s QPN %lx\n",
755                        arbel, cq->cqn, ( is_send ? "send" : "recv" ), qpn );
756                 return -EIO;
757         }
758         qp = wq->qp;
759         arbel_qp = container_of ( qp, struct arbel_queue_pair, qp );
760
761         /* Identify work queue entry index */
762         if ( is_send ) {
763                 arbel_send_wq = &arbel_qp->send;
764                 wqe_idx = ( ( wqe_adr - virt_to_bus ( arbel_send_wq->wqe ) ) /
765                             sizeof ( arbel_send_wq->wqe[0] ) );
766         } else {
767                 arbel_recv_wq = &arbel_qp->recv;
768                 wqe_idx = ( ( wqe_adr - virt_to_bus ( arbel_recv_wq->wqe ) ) /
769                             sizeof ( arbel_recv_wq->wqe[0] ) );
770         }
771
772         /* Identify I/O buffer */
773         iobuf = wq->iobufs[wqe_idx];
774         if ( ! iobuf ) {
775                 DBGC ( arbel, "Arbel %p CQN %lx QPN %lx empty WQE %x\n",
776                        arbel, cq->cqn, qpn, wqe_idx );
777                 return -EIO;
778         }
779         wq->iobufs[wqe_idx] = NULL;
780
781         /* Pass off to caller's completion handler */
782         complete = ( is_send ? complete_send : complete_recv );
783         complete ( ibdev, qp, &completion, iobuf );
784
785         return rc;
786 }                            
787
788 /**
789  * Poll completion queue
790  *
791  * @v ibdev             Infiniband device
792  * @v cq                Completion queue
793  * @v complete_send     Send completion handler
794  * @v complete_recv     Receive completion handler
795  */
796 static void arbel_poll_cq ( struct ib_device *ibdev,
797                             struct ib_completion_queue *cq,
798                             ib_completer_t complete_send,
799                             ib_completer_t complete_recv ) {
800         struct arbel *arbel = ibdev->priv;
801         struct arbel_completion_queue *arbel_cq
802                 = container_of ( cq, struct arbel_completion_queue, cq );
803         union arbelprm_doorbell_record *db_rec;
804         union arbelprm_completion_entry *cqe;
805         unsigned int cqe_idx_mask;
806         int rc;
807
808         while ( 1 ) {
809                 /* Look for completion entry */
810                 cqe_idx_mask = ( cq->num_cqes - 1 );
811                 cqe = &arbel_cq->cqe[cq->next_idx & cqe_idx_mask];
812                 if ( MLX_GET ( &cqe->normal, owner ) != 0 ) {
813                         /* Entry still owned by hardware; end of poll */
814                         break;
815                 }
816
817                 /* Handle completion */
818                 if ( ( rc = arbel_complete ( ibdev, cq, cqe, complete_send,
819                                              complete_recv ) ) != 0 ) {
820                         DBGC ( arbel, "Arbel %p failed to complete: %s\n",
821                                arbel, strerror ( rc ) );
822                         DBGC_HD ( arbel, cqe, sizeof ( *cqe ) );
823                 }
824
825                 /* Return ownership to hardware */
826                 MLX_FILL_1 ( &cqe->normal, 7, owner, 1 );
827                 barrier();
828                 /* Update completion queue's index */
829                 cq->next_idx++;
830                 /* Update doorbell record */
831                 db_rec = &arbel->db_rec[arbel_cq->doorbell_idx];
832                 MLX_FILL_1 ( &db_rec->cq_ci, 0,
833                              counter, ( cq->next_idx & 0xffffffffUL ) );
834         }
835 }
836
837 /** Arbel Infiniband operations */
838 static struct ib_device_operations arbel_ib_operations = {
839         .post_send      = arbel_post_send,
840         .post_recv      = arbel_post_recv,
841         .poll_cq        = arbel_poll_cq,
842 };
843
844 /**
845  * Remove PCI device
846  *
847  * @v pci               PCI device
848  */
849 static void arbel_remove ( struct pci_device *pci ) {
850         struct net_device *netdev = pci_get_drvdata ( pci );
851
852         unregister_netdev ( netdev );
853         ib_driver_close ( 0 );
854         netdev_nullify ( netdev );
855         netdev_put ( netdev );
856 }
857
858 /**
859  * Probe PCI device
860  *
861  * @v pci               PCI device
862  * @v id                PCI ID
863  * @ret rc              Return status code
864  */
865 static int arbel_probe ( struct pci_device *pci,
866                          const struct pci_device_id *id __unused ) {
867         struct net_device *netdev;
868         struct arbelprm_query_dev_lim dev_lim;
869         struct arbel *arbel = &static_arbel;
870         struct mlx_nic *mlx;
871         struct ib_mac *mac;
872         udqp_t qph;
873         int rc;
874
875         /* Allocate net device */
876         netdev = alloc_ibdev ( sizeof ( *mlx ) );
877         if ( ! netdev )
878                 return -ENOMEM;
879         netdev_init ( netdev, &mlx_operations );
880         mlx = netdev->priv;
881         pci_set_drvdata ( pci, netdev );
882         netdev->dev = &pci->dev;
883         memset ( mlx, 0, sizeof ( *mlx ) );
884
885         /* Fix up PCI device */
886         adjust_pci_device ( pci );
887
888         /* Initialise hardware */
889         if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
890                 goto err_ipoib_init;
891         mlx->ipoib_qph = qph;
892         mlx->bcast_av = ib_data.bcast_av;
893         mlx->snd_cqh = ib_data.ipoib_snd_cq;
894         mlx->rcv_cqh = ib_data.ipoib_rcv_cq;
895         mac = ( ( struct ib_mac * ) netdev->ll_addr );
896         mac->qpn = htonl ( ib_get_qpn ( mlx->ipoib_qph ) );
897         memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
898
899         /* Hack up IB structures */
900         static_arbel.config = memfree_pci_dev.cr_space;
901         static_arbel.mailbox_in = dev_buffers_p->inprm_buf;
902         static_arbel.mailbox_out = dev_buffers_p->outprm_buf;
903         static_arbel.uar = memfree_pci_dev.uar;
904         static_arbel.db_rec = dev_ib_data.uar_context_base;
905         static_arbel.reserved_lkey = dev_ib_data.mkey;
906         static_ipoib_qp.send.wqe =
907                 ( ( struct udqp_st * ) qph )->snd_wq;
908         static_ipoib_qp.recv.wqe =
909                 ( ( struct udqp_st * ) qph )->rcv_wq;
910         static_ipoib_send_cq.cqe =
911                 ( ( struct cq_st * ) ib_data.ipoib_snd_cq )->cq_buf;
912         static_ipoib_recv_cq.cqe =
913                 ( ( struct cq_st * ) ib_data.ipoib_rcv_cq )->cq_buf;
914         static_ipoib_qp.qp.qpn = ib_get_qpn ( qph );
915         static_ipoib_qp.qp.priv = netdev;
916         list_add ( &static_ipoib_qp.qp.send.list,
917                    &static_ipoib_send_cq.cq.work_queues );
918         list_add ( &static_ipoib_qp.qp.recv.list,
919                    &static_ipoib_recv_cq.cq.work_queues );
920
921         /* Get device limits */
922         if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
923                 DBGC ( arbel, "Arbel %p could not get device limits: %s\n",
924                        arbel, strerror ( rc ) );
925                 goto err_query_dev_lim;
926         }
927         arbel->limits.reserved_cqs =
928                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
929         DBG ( "Device limits:\n ");
930         DBG_HD ( &dev_lim, sizeof ( dev_lim ) );
931
932         /* Register network device */
933         if ( ( rc = register_netdev ( netdev ) ) != 0 )
934                 goto err_register_netdev;
935
936         return 0;
937
938  err_query_dev_lim:
939  err_register_netdev:
940  err_ipoib_init:
941         ib_driver_close ( 0 );
942         netdev_nullify ( netdev );
943         netdev_put ( netdev );
944         return rc;
945 }
946
947 static struct pci_device_id arbel_nics[] = {
948         PCI_ROM ( 0x15b3, 0x6282, "MT25218", "MT25218 HCA driver" ),
949         PCI_ROM ( 0x15b3, 0x6274, "MT25204", "MT25204 HCA driver" ),
950 };
951
952 struct pci_driver arbel_driver __pci_driver = {
953         .ids = arbel_nics,
954         .id_count = ( sizeof ( arbel_nics ) / sizeof ( arbel_nics[0] ) ),
955         .probe = arbel_probe,
956         .remove = arbel_remove,
957 };