IPoIB code separated out to ipoib.c.
[people/pcmattman/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 #include <gpxe/ipoib.h>
20
21 /* to get some global routines like printf */
22 #include "etherboot.h"
23 /* to get the interface to the body of the program */
24 #include "nic.h"
25
26 #define CREATE_OWN 1
27
28 #include "mt25218_imp.c"
29
30 #include "arbel.h"
31
32
33 struct ib_address_vector hack_ipoib_bcast_av;
34
35
36
37
38 static const struct ib_gid arbel_no_gid = {
39         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }
40 };
41
42
43 #if 0
44
45 #define MLX_RX_MAX_FILL NUM_IPOIB_RCV_WQES
46
47 struct mlx_nic {
48 #if ! CREATE_OWN
49         /** Queue pair handle */
50         udqp_t ipoib_qph;
51         /** Send completion queue */
52         cq_t snd_cqh;
53         /** Receive completion queue */
54         cq_t rcv_cqh;
55 #endif
56         /** Broadcast Address Vector */
57         ud_av_t bcast_av;
58
59         /** RX fill level */
60         unsigned int rx_fill;
61
62 #if CREATE_OWN
63         struct ib_completion_queue *own_send_cq;
64         struct ib_completion_queue *own_recv_cq;
65         struct ib_queue_pair *own_qp;
66 #endif
67 };
68
69
70 static struct io_buffer *static_ipoib_tx_ring[NUM_IPOIB_SND_WQES];
71 static struct io_buffer *static_ipoib_rx_ring[NUM_IPOIB_RCV_WQES];
72
73 static struct arbel static_arbel;
74
75 #if ! CREATE_OWN
76
77 static struct arbel_completion_queue static_arbel_ipoib_send_cq = {
78         .ci_doorbell_idx = IPOIB_SND_CQ_CI_DB_IDX,
79 };
80 static struct ib_completion_queue static_ipoib_send_cq = {
81         .cqn = 1234, /* Only used for debug messages */
82         .num_cqes = NUM_IPOIB_SND_CQES,
83         .work_queues = LIST_HEAD_INIT ( static_ipoib_send_cq.work_queues ),
84         .dev_priv = &static_arbel_ipoib_send_cq,
85 };
86
87 static struct arbel_completion_queue static_arbel_ipoib_recv_cq = {
88         .ci_doorbell_idx = IPOIB_RCV_CQ_CI_DB_IDX,
89 };
90 static struct ib_completion_queue static_ipoib_recv_cq = {
91         .cqn = 2345, /* Only used for debug messages */
92         .num_cqes = NUM_IPOIB_RCV_CQES,
93         .work_queues = LIST_HEAD_INIT ( static_ipoib_recv_cq.work_queues ),
94         .dev_priv = &static_arbel_ipoib_recv_cq,
95 };
96
97 static struct arbel_queue_pair static_arbel_ipoib_qp = {
98         .send = {
99                 .doorbell_idx = IPOIB_SND_QP_DB_IDX,
100         },
101         .recv = {
102                 .doorbell_idx = IPOIB_RCV_QP_DB_IDX,
103         },
104 };
105 static struct ib_queue_pair static_ipoib_qp = {
106         .send = {
107                 .qp = &static_ipoib_qp,
108                 .is_send = 1,
109                 .cq = &static_ipoib_send_cq,
110                 .num_wqes = NUM_IPOIB_SND_WQES,
111                 .iobufs = static_ipoib_tx_ring,
112                 .list = LIST_HEAD_INIT (static_ipoib_qp.send.list),
113                 .dev_priv = &static_arbel_ipoib_qp.send,
114         },
115         .recv = {
116                 .qp = &static_ipoib_qp,
117                 .is_send = 0,
118                 .cq = &static_ipoib_recv_cq,
119                 .num_wqes = NUM_IPOIB_RCV_WQES,
120                 .iobufs = static_ipoib_rx_ring,
121                 .list = LIST_HEAD_INIT (static_ipoib_qp.recv.list),
122                 .dev_priv = &static_arbel_ipoib_qp.recv,
123         },
124         .dev_priv = &static_arbel_ipoib_qp,
125 };
126
127 #endif
128
129
130 static struct ib_device static_ibdev = {
131         .dev_priv = &static_arbel,
132 };
133
134
135 /**
136  * Open network device
137  *
138  * @v netdev            Network device
139  * @ret rc              Return status code
140  */
141 static int mlx_open ( struct net_device *netdev ) {
142
143         ( void ) netdev;
144
145         return 0;
146 }
147
148 /**
149  * Close network device
150  *
151  * @v netdev            Network device
152  */
153 static void mlx_close ( struct net_device *netdev ) {
154
155         ( void ) netdev;
156
157 }
158
159 static int arbel_post_send ( struct ib_device *ibdev,
160                              struct ib_queue_pair *qp,
161                              struct ib_address_vector *av,
162                              struct io_buffer *iobuf );
163
164 static int mlx_transmit_direct ( struct net_device *netdev,
165                                  struct io_buffer *iobuf ) {
166         struct mlx_nic *mlx = netdev->priv;
167         int rc;
168
169         struct ud_av_st *bcast_av = mlx->bcast_av;
170         struct arbelprm_ud_address_vector *bav =
171                 ( struct arbelprm_ud_address_vector * ) &bcast_av->av;
172         struct ib_address_vector av = {
173                 .dest_qp = bcast_av->dest_qp,
174                 .qkey = bcast_av->qkey,
175                 .dlid = MLX_GET ( bav, rlid ),
176                 .rate = ( MLX_GET ( bav, max_stat_rate ) ? 1 : 4 ),
177                 .sl = MLX_GET ( bav, sl ),
178                 .gid_present = 1,
179         };
180         memcpy ( &av.gid, ( ( void * ) bav ) + 16, 16 );
181
182         rc = arbel_post_send ( &static_ibdev,
183 #if CREATE_OWN
184                                mlx->own_qp,
185 #else
186                                &static_ipoib_qp,
187 #endif
188                                &av, iobuf );
189
190         return rc;
191 }
192
193 static void arbel_poll_cq ( struct ib_device *ibdev,
194                             struct ib_completion_queue *cq,
195                             ib_completer_t complete_send,
196                             ib_completer_t complete_recv );
197
198 static void temp_complete_send ( struct ib_device *ibdev __unused,
199                                  struct ib_queue_pair *qp,
200                                  struct ib_completion *completion,
201                                  struct io_buffer *iobuf ) {
202         struct net_device *netdev = qp->owner_priv;
203
204         DBG ( "Wahey! TX completion\n" );
205         netdev_tx_complete_err ( netdev, iobuf,
206                                  ( completion->syndrome ? -EIO : 0 ) );
207 }
208
209 static void temp_complete_recv ( struct ib_device *ibdev __unused,
210                                  struct ib_queue_pair *qp,
211                                  struct ib_completion *completion,
212                                  struct io_buffer *iobuf ) {
213         struct net_device *netdev = qp->owner_priv;
214         struct mlx_nic *mlx = netdev->priv;
215
216         DBG ( "Yay! RX completion on %p len %zx:\n", iobuf, completion->len );
217         if ( completion->syndrome ) {
218                 netdev_rx_err ( netdev, iobuf, -EIO );
219         } else {
220                 iob_put ( iobuf, completion->len );
221                 iob_pull ( iobuf, sizeof ( struct ib_global_route_header ) );
222                 netdev_rx ( netdev, iobuf );
223         }
224
225         mlx->rx_fill--;
226 }
227
228 static int arbel_post_recv ( struct ib_device *ibdev,
229                              struct ib_queue_pair *qp,
230                              struct io_buffer *iobuf );
231
232 static void mlx_refill_rx ( struct net_device *netdev ) {
233         struct mlx_nic *mlx = netdev->priv;
234         struct io_buffer *iobuf;
235         int rc;
236
237         while ( mlx->rx_fill < MLX_RX_MAX_FILL ) {
238                 iobuf = alloc_iob ( 2048 );
239                 if ( ! iobuf )
240                         break;
241                 DBG ( "Posting RX buffer %p:\n", iobuf );
242                 if ( ( rc = arbel_post_recv ( &static_ibdev,
243 #if CREATE_OWN
244                                               mlx->own_qp,
245 #else
246                                               &static_ipoib_qp,
247 #endif
248                                               iobuf ) ) != 0 ) {
249                         free_iob ( iobuf );
250                         break;
251                 }
252                 mlx->rx_fill++;
253         }
254 }
255
256 /**
257  * Poll for completed and received packets
258  *
259  * @v netdev            Network device
260  */
261 static void mlx_poll ( struct net_device *netdev ) {
262         struct mlx_nic *mlx = netdev->priv;
263         int rc;
264
265         if ( ( rc = poll_error_buf() ) != 0 ) {
266                 DBG ( "poll_error_buf() failed: %s\n", strerror ( rc ) );
267                 return;
268         }
269
270         /* Drain event queue.  We can ignore events, since we're going
271          * to just poll all completion queues anyway.
272          */
273         if ( ( rc = drain_eq() ) != 0 ) {
274                 DBG ( "drain_eq() failed: %s\n", strerror ( rc ) );
275                 return;
276         }
277
278         /* Poll completion queues */
279         arbel_poll_cq ( &static_ibdev,
280 #if CREATE_OWN
281                         mlx->own_send_cq,
282 #else
283                         &static_ipoib_send_cq,
284 #endif
285                         temp_complete_send, temp_complete_recv );
286 #if 0
287         arbel_poll_cq ( &static_ibdev,
288 #if CREATE_OWN
289                         mlx->own_recv_cq,
290 #else
291                         &static_ipoib_recv_cq,
292 #endif
293                         temp_complete_send, temp_complete_recv );
294 #endif
295
296         mlx_refill_rx ( netdev );
297 }
298
299 /**
300  * Enable or disable interrupts
301  *
302  * @v netdev            Network device
303  * @v enable            Interrupts should be enabled
304  */
305 static void mlx_irq ( struct net_device *netdev, int enable ) {
306
307         ( void ) netdev;
308         ( void ) enable;
309
310 }
311
312 static struct net_device_operations mlx_operations = {
313         .open           = mlx_open,
314         .close          = mlx_close,
315         .transmit       = mlx_transmit_direct,
316         .poll           = mlx_poll,
317         .irq            = mlx_irq,
318 };
319
320
321 #endif /* 0 */
322
323
324
325 /***************************************************************************
326  *
327  * Queue number allocation
328  *
329  ***************************************************************************
330  */
331
332 /**
333  * Allocate queue number
334  *
335  * @v q_inuse           Queue usage bitmask
336  * @v max_inuse         Maximum number of in-use queues
337  * @ret qn_offset       Free queue number offset, or negative error
338  */
339 static int arbel_alloc_qn_offset ( arbel_bitmask_t *q_inuse,
340                                    unsigned int max_inuse ) {
341         unsigned int qn_offset = 0;
342         arbel_bitmask_t mask = 1;
343
344         while ( qn_offset < max_inuse ) {
345                 if ( ( mask & *q_inuse ) == 0 ) {
346                         *q_inuse |= mask;
347                         return qn_offset;
348                 }
349                 qn_offset++;
350                 mask <<= 1;
351                 if ( ! mask ) {
352                         mask = 1;
353                         q_inuse++;
354                 }
355         }
356         return -ENFILE;
357 }
358
359 /**
360  * Free queue number
361  *
362  * @v q_inuse           Queue usage bitmask
363  * @v qn_offset         Queue number offset
364  */
365 static void arbel_free_qn_offset ( arbel_bitmask_t *q_inuse, int qn_offset ) {
366         arbel_bitmask_t mask;
367
368         mask = ( 1 << ( qn_offset % ( 8 * sizeof ( mask ) ) ) );
369         q_inuse += ( qn_offset / ( 8 * sizeof ( mask ) ) );
370         *q_inuse &= ~mask;
371 }
372
373 /***************************************************************************
374  *
375  * HCA commands
376  *
377  ***************************************************************************
378  */
379
380 /**
381  * Wait for Arbel command completion
382  *
383  * @v arbel             Arbel device
384  * @ret rc              Return status code
385  */
386 static int arbel_cmd_wait ( struct arbel *arbel,
387                             struct arbelprm_hca_command_register *hcr ) {
388         unsigned int wait;
389
390         for ( wait = ARBEL_HCR_MAX_WAIT_MS ; wait ; wait-- ) {
391                 hcr->u.dwords[6] =
392                         readl ( arbel->config + ARBEL_HCR_REG ( 6 ) );
393                 if ( MLX_GET ( hcr, go ) == 0 )
394                         return 0;
395                 mdelay ( 1 );
396         }
397         return -EBUSY;
398 }
399
400 /**
401  * Issue HCA command
402  *
403  * @v arbel             Arbel device
404  * @v command           Command opcode, flags and input/output lengths
405  * @v op_mod            Opcode modifier (0 if no modifier applicable)
406  * @v in                Input parameters
407  * @v in_mod            Input modifier (0 if no modifier applicable)
408  * @v out               Output parameters
409  * @ret rc              Return status code
410  */
411 static int arbel_cmd ( struct arbel *arbel, unsigned long command,
412                        unsigned int op_mod, const void *in,
413                        unsigned int in_mod, void *out ) {
414         struct arbelprm_hca_command_register hcr;
415         unsigned int opcode = ARBEL_HCR_OPCODE ( command );
416         size_t in_len = ARBEL_HCR_IN_LEN ( command );
417         size_t out_len = ARBEL_HCR_OUT_LEN ( command );
418         void *in_buffer;
419         void *out_buffer;
420         unsigned int status;
421         unsigned int i;
422         int rc;
423
424         DBGC ( arbel, "Arbel %p command %02x in %zx%s out %zx%s\n",
425                arbel, opcode, in_len,
426                ( ( command & ARBEL_HCR_IN_MBOX ) ? "(mbox)" : "" ), out_len,
427                ( ( command & ARBEL_HCR_OUT_MBOX ) ? "(mbox)" : "" ) );
428
429         /* Check that HCR is free */
430         if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
431                 DBGC ( arbel, "Arbel %p command interface locked\n", arbel );
432                 return rc;
433         }
434
435         /* Prepare HCR */
436         memset ( &hcr, 0, sizeof ( hcr ) );
437         in_buffer = &hcr.u.dwords[0];
438         if ( in_len && ( command & ARBEL_HCR_IN_MBOX ) ) {
439                 in_buffer = arbel->mailbox_in;
440                 MLX_FILL_1 ( &hcr, 1, in_param_l, virt_to_bus ( in_buffer ) );
441         }
442         memcpy ( in_buffer, in, in_len );
443         MLX_FILL_1 ( &hcr, 2, input_modifier, in_mod );
444         out_buffer = &hcr.u.dwords[3];
445         if ( out_len && ( command & ARBEL_HCR_OUT_MBOX ) ) {
446                 out_buffer = arbel->mailbox_out;
447                 MLX_FILL_1 ( &hcr, 4, out_param_l,
448                              virt_to_bus ( out_buffer ) );
449         }
450         MLX_FILL_3 ( &hcr, 6,
451                      opcode, opcode,
452                      opcode_modifier, op_mod,
453                      go, 1 );
454
455         DBG_HD ( &hcr, sizeof ( hcr ) );
456         if ( in_len ) {
457                 size_t dump_len = in_len;
458                 if ( dump_len > 256 )
459                         dump_len = 256;
460                 DBG ( "Input:\n" );
461                 DBG_HD ( in, dump_len );
462         }
463
464         /* Issue command */
465         for ( i = 0 ; i < ( sizeof ( hcr ) / sizeof ( hcr.u.dwords[0] ) ) ;
466               i++ ) {
467                 writel ( hcr.u.dwords[i],
468                          arbel->config + ARBEL_HCR_REG ( i ) );
469                 barrier();
470         }
471
472         /* Wait for command completion */
473         if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
474                 DBGC ( arbel, "Arbel %p timed out waiting for command:\n",
475                        arbel );
476                 DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
477                 return rc;
478         }
479
480         /* Check command status */
481         status = MLX_GET ( &hcr, status );
482         if ( status != 0 ) {
483                 DBGC ( arbel, "Arbel %p command failed with status %02x:\n",
484                        arbel, status );
485                 DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
486                 return -EIO;
487         }
488
489         /* Read output parameters, if any */
490         hcr.u.dwords[3] = readl ( arbel->config + ARBEL_HCR_REG ( 3 ) );
491         hcr.u.dwords[4] = readl ( arbel->config + ARBEL_HCR_REG ( 4 ) );
492         memcpy ( out, out_buffer, out_len );
493
494         if ( out_len ) {
495                 size_t dump_len = out_len;
496                 if ( dump_len > 256 )
497                         dump_len = 256;
498                 DBG ( "Output:\n" );
499                 DBG_HD ( out, dump_len );
500         }
501
502         return 0;
503 }
504
505 static inline int
506 arbel_cmd_query_dev_lim ( struct arbel *arbel,
507                           struct arbelprm_query_dev_lim *dev_lim ) {
508         return arbel_cmd ( arbel,
509                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_QUERY_DEV_LIM, 
510                                                1, sizeof ( *dev_lim ) ),
511                            0, NULL, 0, dev_lim );
512 }
513
514 static inline int
515 arbel_cmd_sw2hw_cq ( struct arbel *arbel, unsigned long cqn,
516                      const struct arbelprm_completion_queue_context *cqctx ) {
517         return arbel_cmd ( arbel,
518                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_SW2HW_CQ,
519                                               1, sizeof ( *cqctx ) ),
520                            0, cqctx, cqn, NULL );
521 }
522
523 static inline int
524 arbel_cmd_hw2sw_cq ( struct arbel *arbel, unsigned long cqn ) {
525         return arbel_cmd ( arbel,
526                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_HW2SW_CQ ),
527                            1, NULL, cqn, NULL );
528 }
529
530 static inline int
531 arbel_cmd_rst2init_qpee ( struct arbel *arbel, unsigned long qpn,
532                           const struct arbelprm_qp_ee_state_transitions *ctx ){
533         return arbel_cmd ( arbel,
534                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_RST2INIT_QPEE,
535                                               1, sizeof ( *ctx ) ),
536                            0, ctx, qpn, NULL );
537 }
538
539 static inline int
540 arbel_cmd_init2rtr_qpee ( struct arbel *arbel, unsigned long qpn,
541                           const struct arbelprm_qp_ee_state_transitions *ctx ){
542         return arbel_cmd ( arbel,
543                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_INIT2RTR_QPEE,
544                                               1, sizeof ( *ctx ) ),
545                            0, ctx, qpn, NULL );
546 }
547
548 static inline int
549 arbel_cmd_rtr2rts_qpee ( struct arbel *arbel, unsigned long qpn,
550                          const struct arbelprm_qp_ee_state_transitions *ctx ) {
551         return arbel_cmd ( arbel,
552                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_RTR2RTS_QPEE,
553                                               1, sizeof ( *ctx ) ),
554                            0, ctx, qpn, NULL );
555 }
556
557 static inline int
558 arbel_cmd_2rst_qpee ( struct arbel *arbel, unsigned long qpn ) {
559         return arbel_cmd ( arbel,
560                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_2RST_QPEE ),
561                            0x03, NULL, qpn, NULL );
562 }
563
564 static inline int
565 arbel_cmd_mad_ifc ( struct arbel *arbel, union arbelprm_mad *mad ) {
566         return arbel_cmd ( arbel,
567                            ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MAD_IFC,
568                                                  1, sizeof ( *mad ),
569                                                  1, sizeof ( *mad ) ),
570                            0x03, mad, PXE_IB_PORT, mad );
571 }
572
573 static inline int
574 arbel_cmd_read_mgm ( struct arbel *arbel, unsigned int index,
575                      struct arbelprm_mgm_entry *mgm ) {
576         return arbel_cmd ( arbel,
577                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_READ_MGM,
578                                                1, sizeof ( *mgm ) ),
579                            0, NULL, index, mgm );
580 }
581
582 static inline int
583 arbel_cmd_write_mgm ( struct arbel *arbel, unsigned int index,
584                       const struct arbelprm_mgm_entry *mgm ) {
585         return arbel_cmd ( arbel,
586                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_WRITE_MGM,
587                                               1, sizeof ( *mgm ) ),
588                            0, mgm, index, NULL );
589 }
590
591 static inline int
592 arbel_cmd_mgid_hash ( struct arbel *arbel, const struct ib_gid *gid,
593                       struct arbelprm_mgm_hash *hash ) {
594         return arbel_cmd ( arbel,
595                            ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MGID_HASH,
596                                                  1, sizeof ( *gid ),
597                                                  0, sizeof ( *hash ) ),
598                            0, gid, 0, hash );
599 }
600
601 /***************************************************************************
602  *
603  * Completion queue operations
604  *
605  ***************************************************************************
606  */
607
608 /**
609  * Create completion queue
610  *
611  * @v ibdev             Infiniband device
612  * @v cq                Completion queue
613  * @ret rc              Return status code
614  */
615 static int arbel_create_cq ( struct ib_device *ibdev,
616                              struct ib_completion_queue *cq ) {
617         struct arbel *arbel = ibdev->dev_priv;
618         struct arbel_completion_queue *arbel_cq;
619         struct arbelprm_completion_queue_context cqctx;
620         struct arbelprm_cq_ci_db_record *ci_db_rec;
621         struct arbelprm_cq_arm_db_record *arm_db_rec;
622         int cqn_offset;
623         unsigned int i;
624         int rc;
625
626         /* Find a free completion queue number */
627         cqn_offset = arbel_alloc_qn_offset ( arbel->cq_inuse, ARBEL_MAX_CQS );
628         if ( cqn_offset < 0 ) {
629                 DBGC ( arbel, "Arbel %p out of completion queues\n", arbel );
630                 rc = cqn_offset;
631                 goto err_cqn_offset;
632         }
633         cq->cqn = ( arbel->limits.reserved_cqs + cqn_offset );
634
635         /* Allocate control structures */
636         arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
637         if ( ! arbel_cq ) {
638                 rc = -ENOMEM;
639                 goto err_arbel_cq;
640         }
641         arbel_cq->ci_doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
642         arbel_cq->arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
643
644         /* Allocate completion queue itself */
645         arbel_cq->cqe_size = ( cq->num_cqes * sizeof ( arbel_cq->cqe[0] ) );
646         arbel_cq->cqe = malloc_dma ( arbel_cq->cqe_size,
647                                      sizeof ( arbel_cq->cqe[0] ) );
648         if ( ! arbel_cq->cqe ) {
649                 rc = -ENOMEM;
650                 goto err_cqe;
651         }
652         memset ( arbel_cq->cqe, 0, arbel_cq->cqe_size );
653         for ( i = 0 ; i < cq->num_cqes ; i++ ) {
654                 MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
655         }
656         barrier();
657
658         /* Initialise doorbell records */
659         ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
660         MLX_FILL_1 ( ci_db_rec, 0, counter, 0 );
661         MLX_FILL_2 ( ci_db_rec, 1,
662                      res, ARBEL_UAR_RES_CQ_CI,
663                      cq_number, cq->cqn );
664         arm_db_rec = &arbel->db_rec[arbel_cq->arm_doorbell_idx].cq_arm;
665         MLX_FILL_1 ( arm_db_rec, 0, counter, 0 );
666         MLX_FILL_2 ( arm_db_rec, 1,
667                      res, ARBEL_UAR_RES_CQ_ARM,
668                      cq_number, cq->cqn );
669
670         /* Hand queue over to hardware */
671         memset ( &cqctx, 0, sizeof ( cqctx ) );
672         MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
673         MLX_FILL_1 ( &cqctx, 2, start_address_l,
674                      virt_to_bus ( arbel_cq->cqe ) );
675         MLX_FILL_2 ( &cqctx, 3,
676                      usr_page, arbel->limits.reserved_uars,
677                      log_cq_size, fls ( cq->num_cqes - 1 ) );
678         MLX_FILL_1 ( &cqctx, 5, c_eqn, arbel->eqn );
679         MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
680         MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
681         MLX_FILL_1 ( &cqctx, 12, cqn, cq->cqn );
682         MLX_FILL_1 ( &cqctx, 13,
683                      cq_ci_db_record, arbel_cq->ci_doorbell_idx );
684         MLX_FILL_1 ( &cqctx, 14,
685                      cq_state_db_record, arbel_cq->arm_doorbell_idx );
686         if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
687                 DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
688                        arbel, strerror ( rc ) );
689                 goto err_sw2hw_cq;
690         }
691
692         cq->dev_priv = arbel_cq;
693         return 0;
694
695  err_sw2hw_cq:
696         MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
697         MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
698         free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
699  err_cqe:
700         free ( arbel_cq );
701  err_arbel_cq:
702         arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
703  err_cqn_offset:
704         return rc;
705 }
706
707 /**
708  * Destroy completion queue
709  *
710  * @v ibdev             Infiniband device
711  * @v cq                Completion queue
712  */
713 static void arbel_destroy_cq ( struct ib_device *ibdev,
714                                struct ib_completion_queue *cq ) {
715         struct arbel *arbel = ibdev->dev_priv;
716         struct arbel_completion_queue *arbel_cq = cq->dev_priv;
717         struct arbelprm_cq_ci_db_record *ci_db_rec;
718         struct arbelprm_cq_arm_db_record *arm_db_rec;
719         int cqn_offset;
720         int rc;
721
722         /* Take ownership back from hardware */
723         if ( ( rc = arbel_cmd_hw2sw_cq ( arbel, cq->cqn ) ) != 0 ) {
724                 DBGC ( arbel, "Arbel %p FATAL HW2SW_CQ failed on CQN %#lx: "
725                        "%s\n", arbel, cq->cqn, strerror ( rc ) );
726                 /* Leak memory and return; at least we avoid corruption */
727                 return;
728         }
729
730         /* Clear doorbell records */
731         ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
732         arm_db_rec = &arbel->db_rec[arbel_cq->arm_doorbell_idx].cq_arm;
733         MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
734         MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
735
736         /* Free memory */
737         free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
738         free ( arbel_cq );
739
740         /* Mark queue number as free */
741         cqn_offset = ( cq->cqn - arbel->limits.reserved_cqs );
742         arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
743
744         cq->dev_priv = NULL;
745 }
746
747 /***************************************************************************
748  *
749  * Queue pair operations
750  *
751  ***************************************************************************
752  */
753
754 /**
755  * Create send work queue
756  *
757  * @v arbel_send_wq     Send work queue
758  * @v num_wqes          Number of work queue entries
759  * @ret rc              Return status code
760  */
761 static int arbel_create_send_wq ( struct arbel_send_work_queue *arbel_send_wq,
762                                   unsigned int num_wqes ) {
763         struct arbelprm_ud_send_wqe *wqe;
764         struct arbelprm_ud_send_wqe *next_wqe;
765         unsigned int wqe_idx_mask;
766         unsigned int i;
767
768         /* Allocate work queue */
769         arbel_send_wq->wqe_size = ( num_wqes *
770                                     sizeof ( arbel_send_wq->wqe[0] ) );
771         arbel_send_wq->wqe = malloc_dma ( arbel_send_wq->wqe_size,
772                                           sizeof ( arbel_send_wq->wqe[0] ) );
773         if ( ! arbel_send_wq->wqe )
774                 return -ENOMEM;
775         memset ( arbel_send_wq->wqe, 0, arbel_send_wq->wqe_size );
776
777         /* Link work queue entries */
778         wqe_idx_mask = ( num_wqes - 1 );
779         for ( i = 0 ; i < num_wqes ; i++ ) {
780                 wqe = &arbel_send_wq->wqe[i].ud;
781                 next_wqe = &arbel_send_wq->wqe[ ( i + 1 ) & wqe_idx_mask ].ud;
782                 MLX_FILL_1 ( &wqe->next, 0, nda_31_6,
783                              ( virt_to_bus ( next_wqe ) >> 6 ) );
784         }
785         
786         return 0;
787 }
788
789 /**
790  * Create receive work queue
791  *
792  * @v arbel_recv_wq     Receive work queue
793  * @v num_wqes          Number of work queue entries
794  * @ret rc              Return status code
795  */
796 static int arbel_create_recv_wq ( struct arbel_recv_work_queue *arbel_recv_wq,
797                                   unsigned int num_wqes ) {
798         struct arbelprm_recv_wqe *wqe;
799         struct arbelprm_recv_wqe *next_wqe;
800         unsigned int wqe_idx_mask;
801         size_t nds;
802         unsigned int i;
803         unsigned int j;
804
805         /* Allocate work queue */
806         arbel_recv_wq->wqe_size = ( num_wqes *
807                                     sizeof ( arbel_recv_wq->wqe[0] ) );
808         arbel_recv_wq->wqe = malloc_dma ( arbel_recv_wq->wqe_size,
809                                           sizeof ( arbel_recv_wq->wqe[0] ) );
810         if ( ! arbel_recv_wq->wqe )
811                 return -ENOMEM;
812         memset ( arbel_recv_wq->wqe, 0, arbel_recv_wq->wqe_size );
813
814         /* Link work queue entries */
815         wqe_idx_mask = ( num_wqes - 1 );
816         nds = ( ( offsetof ( typeof ( *wqe ), data ) +
817                   sizeof ( wqe->data[0] ) ) >> 4 );
818         for ( i = 0 ; i < num_wqes ; i++ ) {
819                 wqe = &arbel_recv_wq->wqe[i].recv;
820                 next_wqe = &arbel_recv_wq->wqe[( i + 1 ) & wqe_idx_mask].recv;
821                 MLX_FILL_1 ( &wqe->next, 0, nda_31_6,
822                              ( virt_to_bus ( next_wqe ) >> 6 ) );
823                 MLX_FILL_1 ( &wqe->next, 1, nds, ( sizeof ( *wqe ) / 16 ) );
824                 for ( j = 0 ; ( ( ( void * ) &wqe->data[j] ) <
825                                 ( ( void * ) ( wqe + 1 ) ) ) ; j++ ) {
826                         MLX_FILL_1 ( &wqe->data[j], 1,
827                                      l_key, ARBEL_INVALID_LKEY );
828                 }
829         }
830         
831         return 0;
832 }
833
834 /**
835  * Create queue pair
836  *
837  * @v ibdev             Infiniband device
838  * @v qp                Queue pair
839  * @ret rc              Return status code
840  */
841 static int arbel_create_qp ( struct ib_device *ibdev,
842                              struct ib_queue_pair *qp ) {
843         struct arbel *arbel = ibdev->dev_priv;
844         struct arbel_queue_pair *arbel_qp;
845         struct arbelprm_qp_ee_state_transitions qpctx;
846         struct arbelprm_qp_db_record *send_db_rec;
847         struct arbelprm_qp_db_record *recv_db_rec;
848         int qpn_offset;
849         int rc;
850
851         /* Find a free queue pair number */
852         qpn_offset = arbel_alloc_qn_offset ( arbel->qp_inuse, ARBEL_MAX_QPS );
853         if ( qpn_offset < 0 ) {
854                 DBGC ( arbel, "Arbel %p out of queue pairs\n", arbel );
855                 rc = qpn_offset;
856                 goto err_qpn_offset;
857         }
858         qp->qpn = ( ARBEL_QPN_BASE + arbel->limits.reserved_qps + qpn_offset );
859
860         /* Allocate control structures */
861         arbel_qp = zalloc ( sizeof ( *arbel_qp ) );
862         if ( ! arbel_qp ) {
863                 rc = -ENOMEM;
864                 goto err_arbel_qp;
865         }
866         arbel_qp->send.doorbell_idx = arbel_send_doorbell_idx ( qpn_offset );
867         arbel_qp->recv.doorbell_idx = arbel_recv_doorbell_idx ( qpn_offset );
868
869         /* Create send and receive work queues */
870         if ( ( rc = arbel_create_send_wq ( &arbel_qp->send,
871                                            qp->send.num_wqes ) ) != 0 )
872                 goto err_create_send_wq;
873         if ( ( rc = arbel_create_recv_wq ( &arbel_qp->recv,
874                                            qp->recv.num_wqes ) ) != 0 )
875                 goto err_create_recv_wq;
876
877         /* Initialise doorbell records */
878         send_db_rec = &arbel->db_rec[arbel_qp->send.doorbell_idx].qp;
879         MLX_FILL_1 ( send_db_rec, 0, counter, 0 );
880         MLX_FILL_2 ( send_db_rec, 1,
881                      res, ARBEL_UAR_RES_SQ,
882                      qp_number, qp->qpn );
883         recv_db_rec = &arbel->db_rec[arbel_qp->recv.doorbell_idx].qp;
884         MLX_FILL_1 ( recv_db_rec, 0, counter, 0 );
885         MLX_FILL_2 ( recv_db_rec, 1,
886                      res, ARBEL_UAR_RES_RQ,
887                      qp_number, qp->qpn );
888
889         /* Hand queue over to hardware */
890         memset ( &qpctx, 0, sizeof ( qpctx ) );
891         MLX_FILL_3 ( &qpctx, 2,
892                      qpc_eec_data.de, 1,
893                      qpc_eec_data.pm_state, 0x03 /* Always 0x03 for UD */,
894                      qpc_eec_data.st, ARBEL_ST_UD );
895         MLX_FILL_6 ( &qpctx, 4,
896                      qpc_eec_data.mtu, ARBEL_MTU_2048,
897                      qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */,
898                      qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
899                      qpc_eec_data.log_rq_stride,
900                      ( fls ( sizeof ( arbel_qp->recv.wqe[0] ) - 1 ) - 4 ),
901                      qpc_eec_data.log_sq_size, fls ( qp->send.num_wqes - 1 ),
902                      qpc_eec_data.log_sq_stride,
903                      ( fls ( sizeof ( arbel_qp->send.wqe[0] ) - 1 ) - 4 ) );
904         MLX_FILL_1 ( &qpctx, 5,
905                      qpc_eec_data.usr_page, arbel->limits.reserved_uars );
906         MLX_FILL_1 ( &qpctx, 10, qpc_eec_data.primary_address_path.port_number,
907                      PXE_IB_PORT );
908         MLX_FILL_1 ( &qpctx, 27, qpc_eec_data.pd, ARBEL_GLOBAL_PD );
909         MLX_FILL_1 ( &qpctx, 29, qpc_eec_data.wqe_lkey, arbel->reserved_lkey );
910         MLX_FILL_1 ( &qpctx, 30, qpc_eec_data.ssc, 1 );
911         MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
912         MLX_FILL_1 ( &qpctx, 34, qpc_eec_data.snd_wqe_base_adr_l,
913                      ( virt_to_bus ( arbel_qp->send.wqe ) >> 6 ) );
914         MLX_FILL_1 ( &qpctx, 35, qpc_eec_data.snd_db_record_index,
915                      arbel_qp->send.doorbell_idx );
916         MLX_FILL_1 ( &qpctx, 38, qpc_eec_data.rsc, 1 );
917         MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
918         MLX_FILL_1 ( &qpctx, 42, qpc_eec_data.rcv_wqe_base_adr_l,
919                      ( virt_to_bus ( arbel_qp->recv.wqe ) >> 6 ) );
920         MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.rcv_db_record_index,
921                      arbel_qp->recv.doorbell_idx );
922         MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
923         if ( ( rc = arbel_cmd_rst2init_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
924                 DBGC ( arbel, "Arbel %p RST2INIT_QPEE failed: %s\n",
925                        arbel, strerror ( rc ) );
926                 goto err_rst2init_qpee;
927         }
928         memset ( &qpctx, 0, sizeof ( qpctx ) );
929         MLX_FILL_2 ( &qpctx, 4,
930                      qpc_eec_data.mtu, ARBEL_MTU_2048,
931                      qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */ );
932         if ( ( rc = arbel_cmd_init2rtr_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
933                 DBGC ( arbel, "Arbel %p INIT2RTR_QPEE failed: %s\n",
934                        arbel, strerror ( rc ) );
935                 goto err_init2rtr_qpee;
936         }
937         memset ( &qpctx, 0, sizeof ( qpctx ) );
938         if ( ( rc = arbel_cmd_rtr2rts_qpee ( arbel, qp->qpn, &qpctx ) ) != 0 ){
939                 DBGC ( arbel, "Arbel %p RTR2RTS_QPEE failed: %s\n",
940                        arbel, strerror ( rc ) );
941                 goto err_rtr2rts_qpee;
942         }
943
944         qp->dev_priv = arbel_qp;
945         return 0;
946
947  err_rtr2rts_qpee:
948  err_init2rtr_qpee:
949         arbel_cmd_2rst_qpee ( arbel, qp->qpn );
950  err_rst2init_qpee:
951         MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
952         MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
953         free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
954  err_create_recv_wq:
955         free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
956  err_create_send_wq:
957         free ( arbel_qp );
958  err_arbel_qp:
959         arbel_free_qn_offset ( arbel->qp_inuse, qpn_offset );
960  err_qpn_offset:
961         return rc;
962 }
963
964 /**
965  * Destroy queue pair
966  *
967  * @v ibdev             Infiniband device
968  * @v qp                Queue pair
969  */
970 static void arbel_destroy_qp ( struct ib_device *ibdev,
971                                struct ib_queue_pair *qp ) {
972         struct arbel *arbel = ibdev->dev_priv;
973         struct arbel_queue_pair *arbel_qp = qp->dev_priv;
974         struct arbelprm_qp_db_record *send_db_rec;
975         struct arbelprm_qp_db_record *recv_db_rec;
976         int qpn_offset;
977         int rc;
978
979         /* Take ownership back from hardware */
980         if ( ( rc = arbel_cmd_2rst_qpee ( arbel, qp->qpn ) ) != 0 ) {
981                 DBGC ( arbel, "Arbel %p FATAL 2RST_QPEE failed on QPN %#lx: "
982                        "%s\n", arbel, qp->qpn, strerror ( rc ) );
983                 /* Leak memory and return; at least we avoid corruption */
984                 return;
985         }
986
987         /* Clear doorbell records */
988         send_db_rec = &arbel->db_rec[arbel_qp->send.doorbell_idx].qp;
989         recv_db_rec = &arbel->db_rec[arbel_qp->recv.doorbell_idx].qp;
990         MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
991         MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
992
993         /* Free memory */
994         free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
995         free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
996         free ( arbel_qp );
997
998         /* Mark queue number as free */
999         qpn_offset = ( qp->qpn - ARBEL_QPN_BASE - arbel->limits.reserved_qps );
1000         arbel_free_qn_offset ( arbel->qp_inuse, qpn_offset );
1001
1002         qp->dev_priv = NULL;
1003 }
1004
1005 /***************************************************************************
1006  *
1007  * Work request operations
1008  *
1009  ***************************************************************************
1010  */
1011
1012 /**
1013  * Ring doorbell register in UAR
1014  *
1015  * @v arbel             Arbel device
1016  * @v db_reg            Doorbell register structure
1017  * @v offset            Address of doorbell
1018  */
1019 static void arbel_ring_doorbell ( struct arbel *arbel,
1020                                   union arbelprm_doorbell_register *db_reg,
1021                                   unsigned int offset ) {
1022
1023         DBG ( "arbel_ring_doorbell %08lx:%08lx to %lx\n",
1024               db_reg->dword[0], db_reg->dword[1],
1025               virt_to_phys ( arbel->uar + offset ) );
1026
1027         barrier();
1028         writel ( db_reg->dword[0], ( arbel->uar + offset + 0 ) );
1029         barrier();
1030         writel ( db_reg->dword[1], ( arbel->uar + offset + 4 ) );
1031 }
1032
1033 /**
1034  * Post send work queue entry
1035  *
1036  * @v ibdev             Infiniband device
1037  * @v qp                Queue pair
1038  * @v av                Address vector
1039  * @v iobuf             I/O buffer
1040  * @ret rc              Return status code
1041  */
1042 static int arbel_post_send ( struct ib_device *ibdev,
1043                              struct ib_queue_pair *qp,
1044                              struct ib_address_vector *av,
1045                              struct io_buffer *iobuf ) {
1046         struct arbel *arbel = ibdev->dev_priv;
1047         struct arbel_queue_pair *arbel_qp = qp->dev_priv;
1048         struct ib_work_queue *wq = &qp->send;
1049         struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
1050         struct arbelprm_ud_send_wqe *prev_wqe;
1051         struct arbelprm_ud_send_wqe *wqe;
1052         struct arbelprm_qp_db_record *qp_db_rec;
1053         union arbelprm_doorbell_register db_reg;
1054         const struct ib_gid *gid;
1055         unsigned int wqe_idx_mask;
1056         size_t nds;
1057
1058         /* Allocate work queue entry */
1059         wqe_idx_mask = ( wq->num_wqes - 1 );
1060         if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
1061                 DBGC ( arbel, "Arbel %p send queue full", arbel );
1062                 return -ENOBUFS;
1063         }
1064         wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
1065         prev_wqe = &arbel_send_wq->wqe[(wq->next_idx - 1) & wqe_idx_mask].ud;
1066         wqe = &arbel_send_wq->wqe[wq->next_idx & wqe_idx_mask].ud;
1067
1068         /* Construct work queue entry */
1069         MLX_FILL_1 ( &wqe->next, 1, always1, 1 );
1070         memset ( &wqe->ctrl, 0, sizeof ( wqe->ctrl ) );
1071         MLX_FILL_1 ( &wqe->ctrl, 0, always1, 1 );
1072         memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
1073         MLX_FILL_2 ( &wqe->ud, 0,
1074                      ud_address_vector.pd, ARBEL_GLOBAL_PD,
1075                      ud_address_vector.port_number, PXE_IB_PORT );
1076         MLX_FILL_2 ( &wqe->ud, 1,
1077                      ud_address_vector.rlid, av->dlid,
1078                      ud_address_vector.g, av->gid_present );
1079         MLX_FILL_2 ( &wqe->ud, 2,
1080                      ud_address_vector.max_stat_rate,
1081                          ( ( av->rate >= 3 ) ? 0 : 1 ),
1082                      ud_address_vector.msg, 3 );
1083         MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
1084         gid = ( av->gid_present ? &av->gid : &arbel_no_gid );
1085         memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) );
1086         MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->dest_qp );
1087         MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
1088         MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
1089         MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
1090         MLX_FILL_1 ( &wqe->data[0], 3,
1091                      local_address_l, virt_to_bus ( iobuf->data ) );
1092
1093         /* Update previous work queue entry's "next" field */
1094         nds = ( ( offsetof ( typeof ( *wqe ), data ) +
1095                   sizeof ( wqe->data[0] ) ) >> 4 );
1096         MLX_SET ( &prev_wqe->next, nopcode, ARBEL_OPCODE_SEND );
1097         MLX_FILL_3 ( &prev_wqe->next, 1,
1098                      nds, nds,
1099                      f, 1,
1100                      always1, 1 );
1101
1102         /* Update doorbell record */
1103         barrier();
1104         qp_db_rec = &arbel->db_rec[arbel_send_wq->doorbell_idx].qp;
1105         MLX_FILL_1 ( qp_db_rec, 0,
1106                      counter, ( ( wq->next_idx + 1 ) & 0xffff ) );
1107
1108         /* Ring doorbell register */
1109         MLX_FILL_4 ( &db_reg.send, 0,
1110                      nopcode, ARBEL_OPCODE_SEND,
1111                      f, 1,
1112                      wqe_counter, ( wq->next_idx & 0xffff ),
1113                      wqe_cnt, 1 );
1114         MLX_FILL_2 ( &db_reg.send, 1,
1115                      nds, nds,
1116                      qpn, qp->qpn );
1117         arbel_ring_doorbell ( arbel, &db_reg, POST_SND_OFFSET );
1118
1119         /* Update work queue's index */
1120         wq->next_idx++;
1121
1122         return 0;
1123 }
1124
1125 /**
1126  * Post receive work queue entry
1127  *
1128  * @v ibdev             Infiniband device
1129  * @v qp                Queue pair
1130  * @v iobuf             I/O buffer
1131  * @ret rc              Return status code
1132  */
1133 static int arbel_post_recv ( struct ib_device *ibdev,
1134                              struct ib_queue_pair *qp,
1135                              struct io_buffer *iobuf ) {
1136         struct arbel *arbel = ibdev->dev_priv;
1137         struct arbel_queue_pair *arbel_qp = qp->dev_priv;
1138         struct ib_work_queue *wq = &qp->recv;
1139         struct arbel_recv_work_queue *arbel_recv_wq = &arbel_qp->recv;
1140         struct arbelprm_recv_wqe *wqe;
1141         union arbelprm_doorbell_record *db_rec;
1142         unsigned int wqe_idx_mask;
1143
1144         /* Allocate work queue entry */
1145         wqe_idx_mask = ( wq->num_wqes - 1 );
1146         if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
1147                 DBGC ( arbel, "Arbel %p receive queue full", arbel );
1148                 return -ENOBUFS;
1149         }
1150         wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
1151         wqe = &arbel_recv_wq->wqe[wq->next_idx & wqe_idx_mask].recv;
1152
1153         /* Construct work queue entry */
1154         MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
1155         MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
1156         MLX_FILL_1 ( &wqe->data[0], 3,
1157                      local_address_l, virt_to_bus ( iobuf->data ) );
1158
1159         /* Update doorbell record */
1160         barrier();
1161         db_rec = &arbel->db_rec[arbel_recv_wq->doorbell_idx];
1162         MLX_FILL_1 ( &db_rec->qp, 0,
1163                      counter, ( ( wq->next_idx + 1 ) & 0xffff ) );      
1164
1165         /* Update work queue's index */
1166         wq->next_idx++;
1167
1168         return 0;       
1169 }
1170
1171 /**
1172  * Handle completion
1173  *
1174  * @v ibdev             Infiniband device
1175  * @v cq                Completion queue
1176  * @v cqe               Hardware completion queue entry
1177  * @v complete_send     Send completion handler
1178  * @v complete_recv     Receive completion handler
1179  * @ret rc              Return status code
1180  */
1181 static int arbel_complete ( struct ib_device *ibdev,
1182                             struct ib_completion_queue *cq,
1183                             union arbelprm_completion_entry *cqe,
1184                             ib_completer_t complete_send,
1185                             ib_completer_t complete_recv ) {
1186         struct arbel *arbel = ibdev->dev_priv;
1187         struct ib_completion completion;
1188         struct ib_work_queue *wq;
1189         struct ib_queue_pair *qp;
1190         struct arbel_queue_pair *arbel_qp;
1191         struct arbel_send_work_queue *arbel_send_wq;
1192         struct arbel_recv_work_queue *arbel_recv_wq;
1193         struct io_buffer *iobuf;
1194         ib_completer_t complete;
1195         unsigned int opcode;
1196         unsigned long qpn;
1197         int is_send;
1198         unsigned long wqe_adr;
1199         unsigned int wqe_idx;
1200         int rc = 0;
1201
1202         /* Parse completion */
1203         memset ( &completion, 0, sizeof ( completion ) );
1204         completion.len = MLX_GET ( &cqe->normal, byte_cnt );
1205         qpn = MLX_GET ( &cqe->normal, my_qpn );
1206         is_send = MLX_GET ( &cqe->normal, s );
1207         wqe_adr = ( MLX_GET ( &cqe->normal, wqe_adr ) << 6 );
1208         opcode = MLX_GET ( &cqe->normal, opcode );
1209         if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) {
1210                 /* "s" field is not valid for error opcodes */
1211                 is_send = ( opcode == ARBEL_OPCODE_SEND_ERROR );
1212                 completion.syndrome = MLX_GET ( &cqe->error, syndrome );
1213                 DBGC ( arbel, "Arbel %p CPN %lx syndrome %x vendor %lx\n",
1214                        arbel, cq->cqn, completion.syndrome,
1215                        MLX_GET ( &cqe->error, vendor_code ) );
1216                 rc = -EIO;
1217                 /* Don't return immediately; propagate error to completer */
1218         }
1219
1220         /* Identify work queue */
1221         wq = ib_find_wq ( cq, qpn, is_send );
1222         if ( ! wq ) {
1223                 DBGC ( arbel, "Arbel %p CQN %lx unknown %s QPN %lx\n",
1224                        arbel, cq->cqn, ( is_send ? "send" : "recv" ), qpn );
1225                 return -EIO;
1226         }
1227         qp = wq->qp;
1228         arbel_qp = qp->dev_priv;
1229
1230         /* Identify work queue entry index */
1231         if ( is_send ) {
1232                 arbel_send_wq = &arbel_qp->send;
1233                 wqe_idx = ( ( wqe_adr - virt_to_bus ( arbel_send_wq->wqe ) ) /
1234                             sizeof ( arbel_send_wq->wqe[0] ) );
1235         } else {
1236                 arbel_recv_wq = &arbel_qp->recv;
1237                 wqe_idx = ( ( wqe_adr - virt_to_bus ( arbel_recv_wq->wqe ) ) /
1238                             sizeof ( arbel_recv_wq->wqe[0] ) );
1239         }
1240
1241         /* Identify I/O buffer */
1242         iobuf = wq->iobufs[wqe_idx];
1243         if ( ! iobuf ) {
1244                 DBGC ( arbel, "Arbel %p CQN %lx QPN %lx empty WQE %x\n",
1245                        arbel, cq->cqn, qpn, wqe_idx );
1246                 return -EIO;
1247         }
1248         wq->iobufs[wqe_idx] = NULL;
1249
1250         /* Pass off to caller's completion handler */
1251         complete = ( is_send ? complete_send : complete_recv );
1252         complete ( ibdev, qp, &completion, iobuf );
1253
1254         return rc;
1255 }                            
1256
1257 /**
1258  * Drain event queue
1259  *
1260  * @v arbel             Arbel device
1261  */
1262 static void arbel_drain_eq ( struct arbel *arbel ) {
1263 #warning "drain the event queue"
1264 }
1265
1266 /**
1267  * Poll completion queue
1268  *
1269  * @v ibdev             Infiniband device
1270  * @v cq                Completion queue
1271  * @v complete_send     Send completion handler
1272  * @v complete_recv     Receive completion handler
1273  */
1274 static void arbel_poll_cq ( struct ib_device *ibdev,
1275                             struct ib_completion_queue *cq,
1276                             ib_completer_t complete_send,
1277                             ib_completer_t complete_recv ) {
1278         struct arbel *arbel = ibdev->dev_priv;
1279         struct arbel_completion_queue *arbel_cq = cq->dev_priv;
1280         struct arbelprm_cq_ci_db_record *ci_db_rec;
1281         union arbelprm_completion_entry *cqe;
1282         unsigned int cqe_idx_mask;
1283         int rc;
1284
1285         /* Drain the event queue */
1286         arbel_drain_eq ( arbel );
1287
1288         while ( 1 ) {
1289                 /* Look for completion entry */
1290                 cqe_idx_mask = ( cq->num_cqes - 1 );
1291                 cqe = &arbel_cq->cqe[cq->next_idx & cqe_idx_mask];
1292                 if ( MLX_GET ( &cqe->normal, owner ) != 0 ) {
1293                         /* Entry still owned by hardware; end of poll */
1294                         break;
1295                 }
1296
1297                 /* Handle completion */
1298                 if ( ( rc = arbel_complete ( ibdev, cq, cqe, complete_send,
1299                                              complete_recv ) ) != 0 ) {
1300                         DBGC ( arbel, "Arbel %p failed to complete: %s\n",
1301                                arbel, strerror ( rc ) );
1302                         DBGC_HD ( arbel, cqe, sizeof ( *cqe ) );
1303                 }
1304
1305                 /* Return ownership to hardware */
1306                 MLX_FILL_1 ( &cqe->normal, 7, owner, 1 );
1307                 barrier();
1308                 /* Update completion queue's index */
1309                 cq->next_idx++;
1310                 /* Update doorbell record */
1311                 ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
1312                 MLX_FILL_1 ( ci_db_rec, 0,
1313                              counter, ( cq->next_idx & 0xffffffffUL ) );
1314         }
1315 }
1316
1317 /***************************************************************************
1318  *
1319  * Multicast group operations
1320  *
1321  ***************************************************************************
1322  */
1323
1324 /**
1325  * Attach to multicast group
1326  *
1327  * @v ibdev             Infiniband device
1328  * @v qp                Queue pair
1329  * @v gid               Multicast GID
1330  * @ret rc              Return status code
1331  */
1332 static int arbel_mcast_attach ( struct ib_device *ibdev,
1333                                 struct ib_queue_pair *qp,
1334                                 struct ib_gid *gid ) {
1335         struct arbel *arbel = ibdev->dev_priv;
1336         struct arbelprm_mgm_hash hash;
1337         struct arbelprm_mgm_entry mgm;
1338         unsigned int index;
1339         int rc;
1340
1341         /* Generate hash table index */
1342         if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
1343                 DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
1344                        arbel, strerror ( rc ) );
1345                 return rc;
1346         }
1347         index = MLX_GET ( &hash, hash );
1348
1349         /* Check for existing hash table entry */
1350         if ( ( rc = arbel_cmd_read_mgm ( arbel, index, &mgm ) ) != 0 ) {
1351                 DBGC ( arbel, "Arbel %p could not read MGM %#x: %s\n",
1352                        arbel, index, strerror ( rc ) );
1353                 return rc;
1354         }
1355         if ( MLX_GET ( &mgm, mgmqp_0.qi ) != 0 ) {
1356                 /* FIXME: this implementation allows only a single QP
1357                  * per multicast group, and doesn't handle hash
1358                  * collisions.  Sufficient for IPoIB but may need to
1359                  * be extended in future.
1360                  */
1361                 DBGC ( arbel, "Arbel %p MGID index %#x already in use\n",
1362                        arbel, index );
1363                 return -EBUSY;
1364         }
1365
1366         /* Update hash table entry */
1367         MLX_FILL_2 ( &mgm, 8,
1368                      mgmqp_0.qpn_i, qp->qpn,
1369                      mgmqp_0.qi, 1 );
1370         memcpy ( &mgm.u.dwords[4], gid, sizeof ( *gid ) );
1371         if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
1372                 DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
1373                        arbel, index, strerror ( rc ) );
1374                 return rc;
1375         }
1376
1377         return 0;
1378 }
1379
1380 /**
1381  * Detach from multicast group
1382  *
1383  * @v ibdev             Infiniband device
1384  * @v qp                Queue pair
1385  * @v gid               Multicast GID
1386  */
1387 static void arbel_mcast_detach ( struct ib_device *ibdev,
1388                                  struct ib_queue_pair *qp __unused,
1389                                  struct ib_gid *gid ) {
1390         struct arbel *arbel = ibdev->dev_priv;
1391         struct arbelprm_mgm_hash hash;
1392         struct arbelprm_mgm_entry mgm;
1393         unsigned int index;
1394         int rc;
1395
1396         /* Generate hash table index */
1397         if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
1398                 DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
1399                        arbel, strerror ( rc ) );
1400                 return;
1401         }
1402         index = MLX_GET ( &hash, hash );
1403
1404         /* Clear hash table entry */
1405         memset ( &mgm, 0, sizeof ( mgm ) );
1406         if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
1407                 DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
1408                        arbel, index, strerror ( rc ) );
1409                 return;
1410         }
1411 }
1412
1413 /** Arbel Infiniband operations */
1414 static struct ib_device_operations arbel_ib_operations = {
1415         .create_cq      = arbel_create_cq,
1416         .destroy_cq     = arbel_destroy_cq,
1417         .create_qp      = arbel_create_qp,
1418         .destroy_qp     = arbel_destroy_qp,
1419         .post_send      = arbel_post_send,
1420         .post_recv      = arbel_post_recv,
1421         .poll_cq        = arbel_poll_cq,
1422         .mcast_attach   = arbel_mcast_attach,
1423         .mcast_detach   = arbel_mcast_detach,
1424 };
1425
1426
1427 static int arbel_mad_ifc ( struct arbel *arbel,
1428                            union arbelprm_mad *mad ) {
1429         struct ib_mad_hdr *hdr = &mad->mad.mad_hdr;
1430         int rc;
1431
1432         hdr->base_version = IB_MGMT_BASE_VERSION;
1433         if ( ( rc = arbel_cmd_mad_ifc ( arbel, mad ) ) != 0 ) {
1434                 DBGC ( arbel, "Arbel %p could not issue MAD IFC: %s\n",
1435                        arbel, strerror ( rc ) );
1436                 return rc;
1437         }
1438         if ( hdr->status != 0 ) {
1439                 DBGC ( arbel, "Arbel %p MAD IFC status %04x\n",
1440                        arbel, ntohs ( hdr->status ) );
1441                 return -EIO;
1442         }
1443         return 0;
1444 }
1445
1446 static int arbel_get_port_info ( struct arbel *arbel,
1447                                  struct ib_mad_port_info *port_info ) {
1448         union arbelprm_mad mad;
1449         struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1450         int rc;
1451
1452         memset ( &mad, 0, sizeof ( mad ) );
1453         hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1454         hdr->class_version = 1;
1455         hdr->method = IB_MGMT_METHOD_GET;
1456         hdr->attr_id = htons ( IB_SMP_ATTR_PORT_INFO );
1457         hdr->attr_mod = htonl ( PXE_IB_PORT );
1458         if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1459                 DBGC ( arbel, "Arbel %p could not get port info: %s\n",
1460                        arbel, strerror ( rc ) );
1461                 return rc;
1462         }
1463         memcpy ( port_info, &mad.mad.port_info, sizeof ( *port_info ) );
1464         return 0;
1465 }
1466
1467 static int arbel_get_guid_info ( struct arbel *arbel,
1468                                  struct ib_mad_guid_info *guid_info ) {
1469         union arbelprm_mad mad;
1470         struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1471         int rc;
1472
1473         memset ( &mad, 0, sizeof ( mad ) );
1474         hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1475         hdr->class_version = 1;
1476         hdr->method = IB_MGMT_METHOD_GET;
1477         hdr->attr_id = htons ( IB_SMP_ATTR_GUID_INFO );
1478         if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1479                 DBGC ( arbel, "Arbel %p could not get GUID info: %s\n",
1480                        arbel, strerror ( rc ) );
1481                 return rc;
1482         }
1483         memcpy ( guid_info, &mad.mad.guid_info, sizeof ( *guid_info ) );
1484         return 0;
1485 }
1486
1487 static int arbel_get_port_gid ( struct arbel *arbel, struct ib_gid *gid ) {
1488         struct ib_mad_port_info port_info;
1489         struct ib_mad_guid_info guid_info;
1490         int rc;
1491
1492         if ( ( rc = arbel_get_port_info ( arbel, &port_info ) ) != 0 )
1493                 return rc;
1494         if ( ( rc = arbel_get_guid_info ( arbel, &guid_info ) ) != 0 )
1495                 return rc;
1496         memcpy ( &gid->bytes[0], port_info.gid_prefix, 8 );
1497         memcpy ( &gid->bytes[8], guid_info.gid_local, 8 );
1498         return 0;
1499 }
1500
1501
1502
1503 #if 0
1504
1505 /**
1506  * Probe PCI device
1507  *
1508  * @v pci               PCI device
1509  * @v id                PCI ID
1510  * @ret rc              Return status code
1511  */
1512 static int arbel_probe ( struct pci_device *pci,
1513                          const struct pci_device_id *id __unused ) {
1514         struct net_device *netdev;
1515         struct arbelprm_query_dev_lim dev_lim;
1516         struct arbel *arbel = &static_arbel;
1517         struct mlx_nic *mlx;
1518         struct ib_mac *mac;
1519         udqp_t qph;
1520         int rc;
1521
1522         /* Allocate net device */
1523         netdev = alloc_ibdev ( sizeof ( *mlx ) );
1524         if ( ! netdev )
1525                 return -ENOMEM;
1526         netdev_init ( netdev, &mlx_operations );
1527         mlx = netdev->priv;
1528         pci_set_drvdata ( pci, netdev );
1529         netdev->dev = &pci->dev;
1530         memset ( mlx, 0, sizeof ( *mlx ) );
1531
1532         /* Fix up PCI device */
1533         adjust_pci_device ( pci );
1534
1535         /* Initialise hardware */
1536         if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
1537                 goto err_ipoib_init;
1538         mlx->bcast_av = ib_data.bcast_av;
1539 #if ! CREATE_OWN
1540         mlx->ipoib_qph = qph;
1541         mlx->snd_cqh = ib_data.ipoib_snd_cq;
1542         mlx->rcv_cqh = ib_data.ipoib_rcv_cq;
1543         mac = ( ( struct ib_mac * ) netdev->ll_addr );
1544         mac->qpn = htonl ( ib_get_qpn ( mlx->ipoib_qph ) );
1545         memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
1546 #endif
1547
1548         /* Hack up IB structures */
1549         arbel->config = memfree_pci_dev.cr_space;
1550         arbel->mailbox_in = dev_buffers_p->inprm_buf;
1551         arbel->mailbox_out = dev_buffers_p->outprm_buf;
1552         arbel->uar = memfree_pci_dev.uar;
1553         arbel->db_rec = dev_ib_data.uar_context_base;
1554         arbel->reserved_lkey = dev_ib_data.mkey;
1555         arbel->eqn = dev_ib_data.eq.eqn;
1556 #if ! CREATE_OWN
1557         static_arbel_ipoib_qp.send.wqe =
1558                 ( ( struct udqp_st * ) qph )->snd_wq;
1559         static_arbel_ipoib_qp.recv.wqe =
1560                 ( ( struct udqp_st * ) qph )->rcv_wq;
1561         static_arbel_ipoib_send_cq.cqe =
1562                 ( ( struct cq_st * ) ib_data.ipoib_snd_cq )->cq_buf;
1563         static_arbel_ipoib_recv_cq.cqe =
1564                 ( ( struct cq_st * ) ib_data.ipoib_rcv_cq )->cq_buf;
1565         static_ipoib_qp.qpn = ib_get_qpn ( qph );
1566         static_ipoib_qp.owner_priv = netdev;
1567         list_add ( &static_ipoib_qp.send.list,
1568                    &static_ipoib_send_cq.work_queues );
1569         list_add ( &static_ipoib_qp.recv.list,
1570                    &static_ipoib_recv_cq.work_queues );
1571 #endif
1572         static_ibdev.op = &arbel_ib_operations;
1573
1574         /* Get device limits */
1575         if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
1576                 DBGC ( arbel, "Arbel %p could not get device limits: %s\n",
1577                        arbel, strerror ( rc ) );
1578                 goto err_query_dev_lim;
1579         }
1580         arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
1581         arbel->limits.reserved_cqs =
1582                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
1583         arbel->limits.reserved_qps =
1584                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_qps ) );
1585
1586 #if CREATE_OWN
1587         struct ib_device *ibdev = &static_ibdev;
1588         mlx->own_send_cq = ib_create_cq ( ibdev, 32 );
1589         if ( ! mlx->own_send_cq ) {
1590                 DBG ( "Could not create send CQ\n" );
1591                 return -EIO;
1592         }
1593 #if 0
1594         mlx->own_recv_cq = ib_create_cq ( ibdev, 32 );
1595         if ( ! mlx->own_recv_cq ) {
1596                 DBG ( "Could not create send CQ\n" );
1597                 return -EIO;
1598         }
1599 #endif
1600         mlx->own_qp = ib_create_qp ( ibdev, NUM_IPOIB_SND_WQES,
1601                                      mlx->own_send_cq, NUM_IPOIB_RCV_WQES,
1602                                      //mlx->own_recv_cq, ipoib_qkey );
1603                                      mlx->own_send_cq, ipoib_qkey );
1604         if ( ! mlx->own_qp ) {
1605                 DBG ( "Could not create QP\n" );
1606                 return -EIO;
1607         }
1608         mlx->own_qp->owner_priv = netdev;
1609         struct ib_gid *bcast_gid = ( struct ib_gid * ) &ib_data.bcast_gid;
1610         if ( ( rc = ib_mcast_attach ( ibdev, mlx->own_qp,
1611                                       bcast_gid ) ) != 0 ) {
1612                 DBG ( "Could not attach to broadcast GID: %s\n",
1613                       strerror ( rc ) );
1614                 return rc;
1615         }
1616
1617         if ( ( rc = arbel_get_port_gid ( arbel, &ibdev->port_gid ) ) != 0 ) {
1618                 DBGC ( arbel, "Arbel %p could not determine port GID: %s\n",
1619                        arbel, strerror ( rc ) );
1620                 return rc;
1621         }
1622
1623         DBG ( "Port GID:\n" );
1624         DBG_HD ( &ibdev->port_gid, sizeof ( ibdev->port_gid ) );
1625                 
1626
1627         mac = ( ( struct ib_mac * ) netdev->ll_addr );
1628         mac->qpn = htonl ( mlx->own_qp->qpn );
1629         memcpy ( &mac->gid, &ibdev->port_gid, sizeof ( mac->gid ) );    
1630 #endif
1631
1632 #if 0
1633         DBG ( "MADS SND CQN = %#lx\n", dev_ib_data.mads_qp.snd_cq.cqn );
1634         struct ib_completion_queue *test_cq;
1635         test_cq = ib_create_cq ( &static_ibdev, 32 );
1636         if ( test_cq ) {
1637                 DBG ( "Woot: create_cq() passed!\n" );
1638         }
1639 #endif
1640
1641         ibdev->dev = &pci->dev;
1642
1643
1644         struct ud_av_st *bcast_av = mlx->bcast_av;
1645         struct arbelprm_ud_address_vector *bav =
1646                 ( struct arbelprm_ud_address_vector * ) &bcast_av->av;
1647         struct ib_address_vector *av = &hack_ipoib_bcast_av;
1648         av->dest_qp = bcast_av->dest_qp;
1649         av->qkey = bcast_av->qkey;
1650         av->dlid = MLX_GET ( bav, rlid );
1651         av->rate = ( MLX_GET ( bav, max_stat_rate ) ? 1 : 4 );
1652         av->sl = MLX_GET ( bav, sl );
1653         av->gid_present = 1;
1654         memcpy ( &av->gid, ( ( void * ) bav ) + 16, 16 );
1655
1656
1657         /* Register network device */
1658         if ( ( rc = register_netdev ( netdev ) ) != 0 )
1659                 goto err_register_netdev;
1660
1661         return 0;
1662
1663  err_query_dev_lim:
1664  err_register_netdev:
1665  err_ipoib_init:
1666         ib_driver_close ( 0 );
1667         netdev_nullify ( netdev );
1668         netdev_put ( netdev );
1669         return rc;
1670 }
1671
1672 /**
1673  * Remove PCI device
1674  *
1675  * @v pci               PCI device
1676  */
1677 static void arbel_remove ( struct pci_device *pci ) {
1678         struct net_device *netdev = pci_get_drvdata ( pci );
1679
1680         unregister_netdev ( netdev );
1681         ib_driver_close ( 0 );
1682         netdev_nullify ( netdev );
1683         netdev_put ( netdev );
1684 }
1685
1686 #endif /* 0 */
1687
1688
1689
1690 /**
1691  * Probe PCI device
1692  *
1693  * @v pci               PCI device
1694  * @v id                PCI ID
1695  * @ret rc              Return status code
1696  */
1697 static int arbel_probe ( struct pci_device *pci,
1698                          const struct pci_device_id *id __unused ) {
1699         struct ib_device *ibdev;
1700         struct arbelprm_query_dev_lim dev_lim;
1701         struct arbel *arbel;
1702         udqp_t qph;
1703         int rc;
1704
1705         /* Allocate Infiniband device */
1706         ibdev = alloc_ibdev ( sizeof ( *arbel ) );
1707         if ( ! ibdev )
1708                 return -ENOMEM;
1709         ibdev->op = &arbel_ib_operations;
1710         pci_set_drvdata ( pci, ibdev );
1711         ibdev->dev = &pci->dev;
1712         arbel = ibdev->dev_priv;
1713         memset ( arbel, 0, sizeof ( *arbel ) );
1714
1715         /* Fix up PCI device */
1716         adjust_pci_device ( pci );
1717
1718         /* Initialise hardware */
1719         if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
1720                 goto err_ib_driver_init;
1721
1722         /* Hack up IB structures */
1723         arbel->config = memfree_pci_dev.cr_space;
1724         arbel->mailbox_in = dev_buffers_p->inprm_buf;
1725         arbel->mailbox_out = dev_buffers_p->outprm_buf;
1726         arbel->uar = memfree_pci_dev.uar;
1727         arbel->db_rec = dev_ib_data.uar_context_base;
1728         arbel->reserved_lkey = dev_ib_data.mkey;
1729         arbel->eqn = dev_ib_data.eq.eqn;
1730
1731         /* Get device limits */
1732         if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
1733                 DBGC ( arbel, "Arbel %p could not get device limits: %s\n",
1734                        arbel, strerror ( rc ) );
1735                 goto err_query_dev_lim;
1736         }
1737         arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
1738         arbel->limits.reserved_cqs =
1739                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
1740         arbel->limits.reserved_qps =
1741                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_qps ) );
1742
1743         /* Get port GID */
1744         if ( ( rc = arbel_get_port_gid ( arbel, &ibdev->port_gid ) ) != 0 ) {
1745                 DBGC ( arbel, "Arbel %p could not determine port GID: %s\n",
1746                        arbel, strerror ( rc ) );
1747                 goto err_get_port_gid;
1748         }
1749
1750         struct ud_av_st *bcast_av = ib_data.bcast_av;
1751         struct arbelprm_ud_address_vector *bav =
1752                 ( struct arbelprm_ud_address_vector * ) &bcast_av->av;
1753         struct ib_address_vector *av = &hack_ipoib_bcast_av;
1754         av->dest_qp = bcast_av->dest_qp;
1755         av->qkey = bcast_av->qkey;
1756         av->dlid = MLX_GET ( bav, rlid );
1757         av->rate = ( MLX_GET ( bav, max_stat_rate ) ? 1 : 4 );
1758         av->sl = MLX_GET ( bav, sl );
1759         av->gid_present = 1;
1760         memcpy ( &av->gid, ( ( void * ) bav ) + 16, 16 );
1761
1762         memcpy ( &ibdev->broadcast_gid, &ib_data.bcast_gid, 16 );
1763
1764         /* Add IPoIB device */
1765         if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
1766                 DBGC ( arbel, "Arbel %p could not add IPoIB device: %s\n",
1767                        arbel, strerror ( rc ) );
1768                 goto err_ipoib_probe;
1769         }
1770
1771         return 0;
1772
1773  err_ipoib_probe:
1774  err_get_port_gid:
1775  err_query_dev_lim:
1776         ib_driver_close ( 0 );
1777  err_ib_driver_init:
1778         free_ibdev ( ibdev );
1779         return rc;
1780 }
1781
1782 /**
1783  * Remove PCI device
1784  *
1785  * @v pci               PCI device
1786  */
1787 static void arbel_remove ( struct pci_device *pci ) {
1788         struct ib_device *ibdev = pci_get_drvdata ( pci );
1789
1790         ipoib_remove ( ibdev );
1791         ib_driver_close ( 0 );
1792 }
1793
1794 static struct pci_device_id arbel_nics[] = {
1795         PCI_ROM ( 0x15b3, 0x6282, "MT25218", "MT25218 HCA driver" ),
1796         PCI_ROM ( 0x15b3, 0x6274, "MT25204", "MT25204 HCA driver" ),
1797 };
1798
1799 struct pci_driver arbel_driver __pci_driver = {
1800         .ids = arbel_nics,
1801         .id_count = ( sizeof ( arbel_nics ) / sizeof ( arbel_nics[0] ) ),
1802         .probe = arbel_probe,
1803         .remove = arbel_remove,
1804 };