Use pkey table access to determine broadcast GID directly.
[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 #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
39
40
41
42 /***************************************************************************
43  *
44  * Queue number allocation
45  *
46  ***************************************************************************
47  */
48
49 /**
50  * Allocate queue number
51  *
52  * @v q_inuse           Queue usage bitmask
53  * @v max_inuse         Maximum number of in-use queues
54  * @ret qn_offset       Free queue number offset, or negative error
55  */
56 static int arbel_alloc_qn_offset ( arbel_bitmask_t *q_inuse,
57                                    unsigned int max_inuse ) {
58         unsigned int qn_offset = 0;
59         arbel_bitmask_t mask = 1;
60
61         while ( qn_offset < max_inuse ) {
62                 if ( ( mask & *q_inuse ) == 0 ) {
63                         *q_inuse |= mask;
64                         return qn_offset;
65                 }
66                 qn_offset++;
67                 mask <<= 1;
68                 if ( ! mask ) {
69                         mask = 1;
70                         q_inuse++;
71                 }
72         }
73         return -ENFILE;
74 }
75
76 /**
77  * Free queue number
78  *
79  * @v q_inuse           Queue usage bitmask
80  * @v qn_offset         Queue number offset
81  */
82 static void arbel_free_qn_offset ( arbel_bitmask_t *q_inuse, int qn_offset ) {
83         arbel_bitmask_t mask;
84
85         mask = ( 1 << ( qn_offset % ( 8 * sizeof ( mask ) ) ) );
86         q_inuse += ( qn_offset / ( 8 * sizeof ( mask ) ) );
87         *q_inuse &= ~mask;
88 }
89
90 /***************************************************************************
91  *
92  * HCA commands
93  *
94  ***************************************************************************
95  */
96
97 /**
98  * Wait for Arbel command completion
99  *
100  * @v arbel             Arbel device
101  * @ret rc              Return status code
102  */
103 static int arbel_cmd_wait ( struct arbel *arbel,
104                             struct arbelprm_hca_command_register *hcr ) {
105         unsigned int wait;
106
107         for ( wait = ARBEL_HCR_MAX_WAIT_MS ; wait ; wait-- ) {
108                 hcr->u.dwords[6] =
109                         readl ( arbel->config + ARBEL_HCR_REG ( 6 ) );
110                 if ( MLX_GET ( hcr, go ) == 0 )
111                         return 0;
112                 mdelay ( 1 );
113         }
114         return -EBUSY;
115 }
116
117 /**
118  * Issue HCA command
119  *
120  * @v arbel             Arbel device
121  * @v command           Command opcode, flags and input/output lengths
122  * @v op_mod            Opcode modifier (0 if no modifier applicable)
123  * @v in                Input parameters
124  * @v in_mod            Input modifier (0 if no modifier applicable)
125  * @v out               Output parameters
126  * @ret rc              Return status code
127  */
128 static int arbel_cmd ( struct arbel *arbel, unsigned long command,
129                        unsigned int op_mod, const void *in,
130                        unsigned int in_mod, void *out ) {
131         struct arbelprm_hca_command_register hcr;
132         unsigned int opcode = ARBEL_HCR_OPCODE ( command );
133         size_t in_len = ARBEL_HCR_IN_LEN ( command );
134         size_t out_len = ARBEL_HCR_OUT_LEN ( command );
135         void *in_buffer;
136         void *out_buffer;
137         unsigned int status;
138         unsigned int i;
139         int rc;
140
141         DBGC ( arbel, "Arbel %p command %02x in %zx%s out %zx%s\n",
142                arbel, opcode, in_len,
143                ( ( command & ARBEL_HCR_IN_MBOX ) ? "(mbox)" : "" ), out_len,
144                ( ( command & ARBEL_HCR_OUT_MBOX ) ? "(mbox)" : "" ) );
145
146         /* Check that HCR is free */
147         if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
148                 DBGC ( arbel, "Arbel %p command interface locked\n", arbel );
149                 return rc;
150         }
151
152         /* Prepare HCR */
153         memset ( &hcr, 0, sizeof ( hcr ) );
154         in_buffer = &hcr.u.dwords[0];
155         if ( in_len && ( command & ARBEL_HCR_IN_MBOX ) ) {
156                 in_buffer = arbel->mailbox_in;
157                 MLX_FILL_1 ( &hcr, 1, in_param_l, virt_to_bus ( in_buffer ) );
158         }
159         memcpy ( in_buffer, in, in_len );
160         MLX_FILL_1 ( &hcr, 2, input_modifier, in_mod );
161         out_buffer = &hcr.u.dwords[3];
162         if ( out_len && ( command & ARBEL_HCR_OUT_MBOX ) ) {
163                 out_buffer = arbel->mailbox_out;
164                 MLX_FILL_1 ( &hcr, 4, out_param_l,
165                              virt_to_bus ( out_buffer ) );
166         }
167         MLX_FILL_3 ( &hcr, 6,
168                      opcode, opcode,
169                      opcode_modifier, op_mod,
170                      go, 1 );
171
172         DBG_HD ( &hcr, sizeof ( hcr ) );
173         if ( in_len ) {
174                 size_t dump_len = in_len;
175                 if ( dump_len > 256 )
176                         dump_len = 256;
177                 DBG ( "Input:\n" );
178                 DBG_HD ( in, dump_len );
179         }
180
181         /* Issue command */
182         for ( i = 0 ; i < ( sizeof ( hcr ) / sizeof ( hcr.u.dwords[0] ) ) ;
183               i++ ) {
184                 writel ( hcr.u.dwords[i],
185                          arbel->config + ARBEL_HCR_REG ( i ) );
186                 barrier();
187         }
188
189         /* Wait for command completion */
190         if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
191                 DBGC ( arbel, "Arbel %p timed out waiting for command:\n",
192                        arbel );
193                 DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
194                 return rc;
195         }
196
197         /* Check command status */
198         status = MLX_GET ( &hcr, status );
199         if ( status != 0 ) {
200                 DBGC ( arbel, "Arbel %p command failed with status %02x:\n",
201                        arbel, status );
202                 DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
203                 return -EIO;
204         }
205
206         /* Read output parameters, if any */
207         hcr.u.dwords[3] = readl ( arbel->config + ARBEL_HCR_REG ( 3 ) );
208         hcr.u.dwords[4] = readl ( arbel->config + ARBEL_HCR_REG ( 4 ) );
209         memcpy ( out, out_buffer, out_len );
210
211         if ( out_len ) {
212                 size_t dump_len = out_len;
213                 if ( dump_len > 256 )
214                         dump_len = 256;
215                 DBG ( "Output:\n" );
216                 DBG_HD ( out, dump_len );
217         }
218
219         return 0;
220 }
221
222 static inline int
223 arbel_cmd_query_dev_lim ( struct arbel *arbel,
224                           struct arbelprm_query_dev_lim *dev_lim ) {
225         return arbel_cmd ( arbel,
226                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_QUERY_DEV_LIM, 
227                                                1, sizeof ( *dev_lim ) ),
228                            0, NULL, 0, dev_lim );
229 }
230
231 static inline int
232 arbel_cmd_sw2hw_cq ( struct arbel *arbel, unsigned long cqn,
233                      const struct arbelprm_completion_queue_context *cqctx ) {
234         return arbel_cmd ( arbel,
235                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_SW2HW_CQ,
236                                               1, sizeof ( *cqctx ) ),
237                            0, cqctx, cqn, NULL );
238 }
239
240 static inline int
241 arbel_cmd_hw2sw_cq ( struct arbel *arbel, unsigned long cqn ) {
242         return arbel_cmd ( arbel,
243                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_HW2SW_CQ ),
244                            1, NULL, cqn, NULL );
245 }
246
247 static inline int
248 arbel_cmd_rst2init_qpee ( struct arbel *arbel, unsigned long qpn,
249                           const struct arbelprm_qp_ee_state_transitions *ctx ){
250         return arbel_cmd ( arbel,
251                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_RST2INIT_QPEE,
252                                               1, sizeof ( *ctx ) ),
253                            0, ctx, qpn, NULL );
254 }
255
256 static inline int
257 arbel_cmd_init2rtr_qpee ( struct arbel *arbel, unsigned long qpn,
258                           const struct arbelprm_qp_ee_state_transitions *ctx ){
259         return arbel_cmd ( arbel,
260                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_INIT2RTR_QPEE,
261                                               1, sizeof ( *ctx ) ),
262                            0, ctx, qpn, NULL );
263 }
264
265 static inline int
266 arbel_cmd_rtr2rts_qpee ( struct arbel *arbel, unsigned long qpn,
267                          const struct arbelprm_qp_ee_state_transitions *ctx ) {
268         return arbel_cmd ( arbel,
269                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_RTR2RTS_QPEE,
270                                               1, sizeof ( *ctx ) ),
271                            0, ctx, qpn, NULL );
272 }
273
274 static inline int
275 arbel_cmd_2rst_qpee ( struct arbel *arbel, unsigned long qpn ) {
276         return arbel_cmd ( arbel,
277                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_2RST_QPEE ),
278                            0x03, NULL, qpn, NULL );
279 }
280
281 static inline int
282 arbel_cmd_mad_ifc ( struct arbel *arbel, union arbelprm_mad *mad ) {
283         return arbel_cmd ( arbel,
284                            ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MAD_IFC,
285                                                  1, sizeof ( *mad ),
286                                                  1, sizeof ( *mad ) ),
287                            0x03, mad, PXE_IB_PORT, mad );
288 }
289
290 static inline int
291 arbel_cmd_read_mgm ( struct arbel *arbel, unsigned int index,
292                      struct arbelprm_mgm_entry *mgm ) {
293         return arbel_cmd ( arbel,
294                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_READ_MGM,
295                                                1, sizeof ( *mgm ) ),
296                            0, NULL, index, mgm );
297 }
298
299 static inline int
300 arbel_cmd_write_mgm ( struct arbel *arbel, unsigned int index,
301                       const struct arbelprm_mgm_entry *mgm ) {
302         return arbel_cmd ( arbel,
303                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_WRITE_MGM,
304                                               1, sizeof ( *mgm ) ),
305                            0, mgm, index, NULL );
306 }
307
308 static inline int
309 arbel_cmd_mgid_hash ( struct arbel *arbel, const struct ib_gid *gid,
310                       struct arbelprm_mgm_hash *hash ) {
311         return arbel_cmd ( arbel,
312                            ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MGID_HASH,
313                                                  1, sizeof ( *gid ),
314                                                  0, sizeof ( *hash ) ),
315                            0, gid, 0, hash );
316 }
317
318 /***************************************************************************
319  *
320  * Completion queue operations
321  *
322  ***************************************************************************
323  */
324
325 /**
326  * Create completion queue
327  *
328  * @v ibdev             Infiniband device
329  * @v cq                Completion queue
330  * @ret rc              Return status code
331  */
332 static int arbel_create_cq ( struct ib_device *ibdev,
333                              struct ib_completion_queue *cq ) {
334         struct arbel *arbel = ibdev->dev_priv;
335         struct arbel_completion_queue *arbel_cq;
336         struct arbelprm_completion_queue_context cqctx;
337         struct arbelprm_cq_ci_db_record *ci_db_rec;
338         struct arbelprm_cq_arm_db_record *arm_db_rec;
339         int cqn_offset;
340         unsigned int i;
341         int rc;
342
343         /* Find a free completion queue number */
344         cqn_offset = arbel_alloc_qn_offset ( arbel->cq_inuse, ARBEL_MAX_CQS );
345         if ( cqn_offset < 0 ) {
346                 DBGC ( arbel, "Arbel %p out of completion queues\n", arbel );
347                 rc = cqn_offset;
348                 goto err_cqn_offset;
349         }
350         cq->cqn = ( arbel->limits.reserved_cqs + cqn_offset );
351
352         /* Allocate control structures */
353         arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
354         if ( ! arbel_cq ) {
355                 rc = -ENOMEM;
356                 goto err_arbel_cq;
357         }
358         arbel_cq->ci_doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
359         arbel_cq->arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
360
361         /* Allocate completion queue itself */
362         arbel_cq->cqe_size = ( cq->num_cqes * sizeof ( arbel_cq->cqe[0] ) );
363         arbel_cq->cqe = malloc_dma ( arbel_cq->cqe_size,
364                                      sizeof ( arbel_cq->cqe[0] ) );
365         if ( ! arbel_cq->cqe ) {
366                 rc = -ENOMEM;
367                 goto err_cqe;
368         }
369         memset ( arbel_cq->cqe, 0, arbel_cq->cqe_size );
370         for ( i = 0 ; i < cq->num_cqes ; i++ ) {
371                 MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
372         }
373         barrier();
374
375         /* Initialise doorbell records */
376         ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
377         MLX_FILL_1 ( ci_db_rec, 0, counter, 0 );
378         MLX_FILL_2 ( ci_db_rec, 1,
379                      res, ARBEL_UAR_RES_CQ_CI,
380                      cq_number, cq->cqn );
381         arm_db_rec = &arbel->db_rec[arbel_cq->arm_doorbell_idx].cq_arm;
382         MLX_FILL_1 ( arm_db_rec, 0, counter, 0 );
383         MLX_FILL_2 ( arm_db_rec, 1,
384                      res, ARBEL_UAR_RES_CQ_ARM,
385                      cq_number, cq->cqn );
386
387         /* Hand queue over to hardware */
388         memset ( &cqctx, 0, sizeof ( cqctx ) );
389         MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
390         MLX_FILL_1 ( &cqctx, 2, start_address_l,
391                      virt_to_bus ( arbel_cq->cqe ) );
392         MLX_FILL_2 ( &cqctx, 3,
393                      usr_page, arbel->limits.reserved_uars,
394                      log_cq_size, fls ( cq->num_cqes - 1 ) );
395         MLX_FILL_1 ( &cqctx, 5, c_eqn, arbel->eqn );
396         MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
397         MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
398         MLX_FILL_1 ( &cqctx, 12, cqn, cq->cqn );
399         MLX_FILL_1 ( &cqctx, 13,
400                      cq_ci_db_record, arbel_cq->ci_doorbell_idx );
401         MLX_FILL_1 ( &cqctx, 14,
402                      cq_state_db_record, arbel_cq->arm_doorbell_idx );
403         if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
404                 DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
405                        arbel, strerror ( rc ) );
406                 goto err_sw2hw_cq;
407         }
408
409         cq->dev_priv = arbel_cq;
410         return 0;
411
412  err_sw2hw_cq:
413         MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
414         MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
415         free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
416  err_cqe:
417         free ( arbel_cq );
418  err_arbel_cq:
419         arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
420  err_cqn_offset:
421         return rc;
422 }
423
424 /**
425  * Destroy completion queue
426  *
427  * @v ibdev             Infiniband device
428  * @v cq                Completion queue
429  */
430 static void arbel_destroy_cq ( struct ib_device *ibdev,
431                                struct ib_completion_queue *cq ) {
432         struct arbel *arbel = ibdev->dev_priv;
433         struct arbel_completion_queue *arbel_cq = cq->dev_priv;
434         struct arbelprm_cq_ci_db_record *ci_db_rec;
435         struct arbelprm_cq_arm_db_record *arm_db_rec;
436         int cqn_offset;
437         int rc;
438
439         /* Take ownership back from hardware */
440         if ( ( rc = arbel_cmd_hw2sw_cq ( arbel, cq->cqn ) ) != 0 ) {
441                 DBGC ( arbel, "Arbel %p FATAL HW2SW_CQ failed on CQN %#lx: "
442                        "%s\n", arbel, cq->cqn, strerror ( rc ) );
443                 /* Leak memory and return; at least we avoid corruption */
444                 return;
445         }
446
447         /* Clear doorbell records */
448         ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
449         arm_db_rec = &arbel->db_rec[arbel_cq->arm_doorbell_idx].cq_arm;
450         MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
451         MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
452
453         /* Free memory */
454         free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
455         free ( arbel_cq );
456
457         /* Mark queue number as free */
458         cqn_offset = ( cq->cqn - arbel->limits.reserved_cqs );
459         arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
460
461         cq->dev_priv = NULL;
462 }
463
464 /***************************************************************************
465  *
466  * Queue pair operations
467  *
468  ***************************************************************************
469  */
470
471 /**
472  * Create send work queue
473  *
474  * @v arbel_send_wq     Send work queue
475  * @v num_wqes          Number of work queue entries
476  * @ret rc              Return status code
477  */
478 static int arbel_create_send_wq ( struct arbel_send_work_queue *arbel_send_wq,
479                                   unsigned int num_wqes ) {
480         struct arbelprm_ud_send_wqe *wqe;
481         struct arbelprm_ud_send_wqe *next_wqe;
482         unsigned int wqe_idx_mask;
483         unsigned int i;
484
485         /* Allocate work queue */
486         arbel_send_wq->wqe_size = ( num_wqes *
487                                     sizeof ( arbel_send_wq->wqe[0] ) );
488         arbel_send_wq->wqe = malloc_dma ( arbel_send_wq->wqe_size,
489                                           sizeof ( arbel_send_wq->wqe[0] ) );
490         if ( ! arbel_send_wq->wqe )
491                 return -ENOMEM;
492         memset ( arbel_send_wq->wqe, 0, arbel_send_wq->wqe_size );
493
494         /* Link work queue entries */
495         wqe_idx_mask = ( num_wqes - 1 );
496         for ( i = 0 ; i < num_wqes ; i++ ) {
497                 wqe = &arbel_send_wq->wqe[i].ud;
498                 next_wqe = &arbel_send_wq->wqe[ ( i + 1 ) & wqe_idx_mask ].ud;
499                 MLX_FILL_1 ( &wqe->next, 0, nda_31_6,
500                              ( virt_to_bus ( next_wqe ) >> 6 ) );
501         }
502         
503         return 0;
504 }
505
506 /**
507  * Create receive work queue
508  *
509  * @v arbel_recv_wq     Receive work queue
510  * @v num_wqes          Number of work queue entries
511  * @ret rc              Return status code
512  */
513 static int arbel_create_recv_wq ( struct arbel_recv_work_queue *arbel_recv_wq,
514                                   unsigned int num_wqes ) {
515         struct arbelprm_recv_wqe *wqe;
516         struct arbelprm_recv_wqe *next_wqe;
517         unsigned int wqe_idx_mask;
518         size_t nds;
519         unsigned int i;
520         unsigned int j;
521
522         /* Allocate work queue */
523         arbel_recv_wq->wqe_size = ( num_wqes *
524                                     sizeof ( arbel_recv_wq->wqe[0] ) );
525         arbel_recv_wq->wqe = malloc_dma ( arbel_recv_wq->wqe_size,
526                                           sizeof ( arbel_recv_wq->wqe[0] ) );
527         if ( ! arbel_recv_wq->wqe )
528                 return -ENOMEM;
529         memset ( arbel_recv_wq->wqe, 0, arbel_recv_wq->wqe_size );
530
531         /* Link work queue entries */
532         wqe_idx_mask = ( num_wqes - 1 );
533         nds = ( ( offsetof ( typeof ( *wqe ), data ) +
534                   sizeof ( wqe->data[0] ) ) >> 4 );
535         for ( i = 0 ; i < num_wqes ; i++ ) {
536                 wqe = &arbel_recv_wq->wqe[i].recv;
537                 next_wqe = &arbel_recv_wq->wqe[( i + 1 ) & wqe_idx_mask].recv;
538                 MLX_FILL_1 ( &wqe->next, 0, nda_31_6,
539                              ( virt_to_bus ( next_wqe ) >> 6 ) );
540                 MLX_FILL_1 ( &wqe->next, 1, nds, ( sizeof ( *wqe ) / 16 ) );
541                 for ( j = 0 ; ( ( ( void * ) &wqe->data[j] ) <
542                                 ( ( void * ) ( wqe + 1 ) ) ) ; j++ ) {
543                         MLX_FILL_1 ( &wqe->data[j], 1,
544                                      l_key, ARBEL_INVALID_LKEY );
545                 }
546         }
547         
548         return 0;
549 }
550
551 /**
552  * Create queue pair
553  *
554  * @v ibdev             Infiniband device
555  * @v qp                Queue pair
556  * @ret rc              Return status code
557  */
558 static int arbel_create_qp ( struct ib_device *ibdev,
559                              struct ib_queue_pair *qp ) {
560         struct arbel *arbel = ibdev->dev_priv;
561         struct arbel_queue_pair *arbel_qp;
562         struct arbelprm_qp_ee_state_transitions qpctx;
563         struct arbelprm_qp_db_record *send_db_rec;
564         struct arbelprm_qp_db_record *recv_db_rec;
565         int qpn_offset;
566         int rc;
567
568         /* Find a free queue pair number */
569         qpn_offset = arbel_alloc_qn_offset ( arbel->qp_inuse, ARBEL_MAX_QPS );
570         if ( qpn_offset < 0 ) {
571                 DBGC ( arbel, "Arbel %p out of queue pairs\n", arbel );
572                 rc = qpn_offset;
573                 goto err_qpn_offset;
574         }
575         qp->qpn = ( ARBEL_QPN_BASE + arbel->limits.reserved_qps + qpn_offset );
576
577         /* Allocate control structures */
578         arbel_qp = zalloc ( sizeof ( *arbel_qp ) );
579         if ( ! arbel_qp ) {
580                 rc = -ENOMEM;
581                 goto err_arbel_qp;
582         }
583         arbel_qp->send.doorbell_idx = arbel_send_doorbell_idx ( qpn_offset );
584         arbel_qp->recv.doorbell_idx = arbel_recv_doorbell_idx ( qpn_offset );
585
586         /* Create send and receive work queues */
587         if ( ( rc = arbel_create_send_wq ( &arbel_qp->send,
588                                            qp->send.num_wqes ) ) != 0 )
589                 goto err_create_send_wq;
590         if ( ( rc = arbel_create_recv_wq ( &arbel_qp->recv,
591                                            qp->recv.num_wqes ) ) != 0 )
592                 goto err_create_recv_wq;
593
594         /* Initialise doorbell records */
595         send_db_rec = &arbel->db_rec[arbel_qp->send.doorbell_idx].qp;
596         MLX_FILL_1 ( send_db_rec, 0, counter, 0 );
597         MLX_FILL_2 ( send_db_rec, 1,
598                      res, ARBEL_UAR_RES_SQ,
599                      qp_number, qp->qpn );
600         recv_db_rec = &arbel->db_rec[arbel_qp->recv.doorbell_idx].qp;
601         MLX_FILL_1 ( recv_db_rec, 0, counter, 0 );
602         MLX_FILL_2 ( recv_db_rec, 1,
603                      res, ARBEL_UAR_RES_RQ,
604                      qp_number, qp->qpn );
605
606         /* Hand queue over to hardware */
607         memset ( &qpctx, 0, sizeof ( qpctx ) );
608         MLX_FILL_3 ( &qpctx, 2,
609                      qpc_eec_data.de, 1,
610                      qpc_eec_data.pm_state, 0x03 /* Always 0x03 for UD */,
611                      qpc_eec_data.st, ARBEL_ST_UD );
612         MLX_FILL_6 ( &qpctx, 4,
613                      qpc_eec_data.mtu, ARBEL_MTU_2048,
614                      qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */,
615                      qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
616                      qpc_eec_data.log_rq_stride,
617                      ( fls ( sizeof ( arbel_qp->recv.wqe[0] ) - 1 ) - 4 ),
618                      qpc_eec_data.log_sq_size, fls ( qp->send.num_wqes - 1 ),
619                      qpc_eec_data.log_sq_stride,
620                      ( fls ( sizeof ( arbel_qp->send.wqe[0] ) - 1 ) - 4 ) );
621         MLX_FILL_1 ( &qpctx, 5,
622                      qpc_eec_data.usr_page, arbel->limits.reserved_uars );
623         MLX_FILL_1 ( &qpctx, 10, qpc_eec_data.primary_address_path.port_number,
624                      PXE_IB_PORT );
625         MLX_FILL_1 ( &qpctx, 27, qpc_eec_data.pd, ARBEL_GLOBAL_PD );
626         MLX_FILL_1 ( &qpctx, 29, qpc_eec_data.wqe_lkey, arbel->reserved_lkey );
627         MLX_FILL_1 ( &qpctx, 30, qpc_eec_data.ssc, 1 );
628         MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
629         MLX_FILL_1 ( &qpctx, 34, qpc_eec_data.snd_wqe_base_adr_l,
630                      ( virt_to_bus ( arbel_qp->send.wqe ) >> 6 ) );
631         MLX_FILL_1 ( &qpctx, 35, qpc_eec_data.snd_db_record_index,
632                      arbel_qp->send.doorbell_idx );
633         MLX_FILL_1 ( &qpctx, 38, qpc_eec_data.rsc, 1 );
634         MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
635         MLX_FILL_1 ( &qpctx, 42, qpc_eec_data.rcv_wqe_base_adr_l,
636                      ( virt_to_bus ( arbel_qp->recv.wqe ) >> 6 ) );
637         MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.rcv_db_record_index,
638                      arbel_qp->recv.doorbell_idx );
639         MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
640         if ( ( rc = arbel_cmd_rst2init_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
641                 DBGC ( arbel, "Arbel %p RST2INIT_QPEE failed: %s\n",
642                        arbel, strerror ( rc ) );
643                 goto err_rst2init_qpee;
644         }
645         memset ( &qpctx, 0, sizeof ( qpctx ) );
646         MLX_FILL_2 ( &qpctx, 4,
647                      qpc_eec_data.mtu, ARBEL_MTU_2048,
648                      qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */ );
649         if ( ( rc = arbel_cmd_init2rtr_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
650                 DBGC ( arbel, "Arbel %p INIT2RTR_QPEE failed: %s\n",
651                        arbel, strerror ( rc ) );
652                 goto err_init2rtr_qpee;
653         }
654         memset ( &qpctx, 0, sizeof ( qpctx ) );
655         if ( ( rc = arbel_cmd_rtr2rts_qpee ( arbel, qp->qpn, &qpctx ) ) != 0 ){
656                 DBGC ( arbel, "Arbel %p RTR2RTS_QPEE failed: %s\n",
657                        arbel, strerror ( rc ) );
658                 goto err_rtr2rts_qpee;
659         }
660
661         qp->dev_priv = arbel_qp;
662         return 0;
663
664  err_rtr2rts_qpee:
665  err_init2rtr_qpee:
666         arbel_cmd_2rst_qpee ( arbel, qp->qpn );
667  err_rst2init_qpee:
668         MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
669         MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
670         free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
671  err_create_recv_wq:
672         free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
673  err_create_send_wq:
674         free ( arbel_qp );
675  err_arbel_qp:
676         arbel_free_qn_offset ( arbel->qp_inuse, qpn_offset );
677  err_qpn_offset:
678         return rc;
679 }
680
681 /**
682  * Destroy queue pair
683  *
684  * @v ibdev             Infiniband device
685  * @v qp                Queue pair
686  */
687 static void arbel_destroy_qp ( struct ib_device *ibdev,
688                                struct ib_queue_pair *qp ) {
689         struct arbel *arbel = ibdev->dev_priv;
690         struct arbel_queue_pair *arbel_qp = qp->dev_priv;
691         struct arbelprm_qp_db_record *send_db_rec;
692         struct arbelprm_qp_db_record *recv_db_rec;
693         int qpn_offset;
694         int rc;
695
696         /* Take ownership back from hardware */
697         if ( ( rc = arbel_cmd_2rst_qpee ( arbel, qp->qpn ) ) != 0 ) {
698                 DBGC ( arbel, "Arbel %p FATAL 2RST_QPEE failed on QPN %#lx: "
699                        "%s\n", arbel, qp->qpn, strerror ( rc ) );
700                 /* Leak memory and return; at least we avoid corruption */
701                 return;
702         }
703
704         /* Clear doorbell records */
705         send_db_rec = &arbel->db_rec[arbel_qp->send.doorbell_idx].qp;
706         recv_db_rec = &arbel->db_rec[arbel_qp->recv.doorbell_idx].qp;
707         MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
708         MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
709
710         /* Free memory */
711         free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
712         free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
713         free ( arbel_qp );
714
715         /* Mark queue number as free */
716         qpn_offset = ( qp->qpn - ARBEL_QPN_BASE - arbel->limits.reserved_qps );
717         arbel_free_qn_offset ( arbel->qp_inuse, qpn_offset );
718
719         qp->dev_priv = NULL;
720 }
721
722 /***************************************************************************
723  *
724  * Work request operations
725  *
726  ***************************************************************************
727  */
728
729 /**
730  * Ring doorbell register in UAR
731  *
732  * @v arbel             Arbel device
733  * @v db_reg            Doorbell register structure
734  * @v offset            Address of doorbell
735  */
736 static void arbel_ring_doorbell ( struct arbel *arbel,
737                                   union arbelprm_doorbell_register *db_reg,
738                                   unsigned int offset ) {
739
740         DBG ( "arbel_ring_doorbell %08lx:%08lx to %lx\n",
741               db_reg->dword[0], db_reg->dword[1],
742               virt_to_phys ( arbel->uar + offset ) );
743
744         barrier();
745         writel ( db_reg->dword[0], ( arbel->uar + offset + 0 ) );
746         barrier();
747         writel ( db_reg->dword[1], ( arbel->uar + offset + 4 ) );
748 }
749
750 /** GID used for GID-less send work queue entries */
751 static const struct ib_gid arbel_no_gid = {
752         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }
753 };
754
755 /**
756  * Post send work queue entry
757  *
758  * @v ibdev             Infiniband device
759  * @v qp                Queue pair
760  * @v av                Address vector
761  * @v iobuf             I/O buffer
762  * @ret rc              Return status code
763  */
764 static int arbel_post_send ( struct ib_device *ibdev,
765                              struct ib_queue_pair *qp,
766                              struct ib_address_vector *av,
767                              struct io_buffer *iobuf ) {
768         struct arbel *arbel = ibdev->dev_priv;
769         struct arbel_queue_pair *arbel_qp = qp->dev_priv;
770         struct ib_work_queue *wq = &qp->send;
771         struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
772         struct arbelprm_ud_send_wqe *prev_wqe;
773         struct arbelprm_ud_send_wqe *wqe;
774         struct arbelprm_qp_db_record *qp_db_rec;
775         union arbelprm_doorbell_register db_reg;
776         const struct ib_gid *gid;
777         unsigned int wqe_idx_mask;
778         size_t nds;
779
780         /* Allocate work queue entry */
781         wqe_idx_mask = ( wq->num_wqes - 1 );
782         if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
783                 DBGC ( arbel, "Arbel %p send queue full", arbel );
784                 return -ENOBUFS;
785         }
786         wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
787         prev_wqe = &arbel_send_wq->wqe[(wq->next_idx - 1) & wqe_idx_mask].ud;
788         wqe = &arbel_send_wq->wqe[wq->next_idx & wqe_idx_mask].ud;
789
790         /* Construct work queue entry */
791         MLX_FILL_1 ( &wqe->next, 1, always1, 1 );
792         memset ( &wqe->ctrl, 0, sizeof ( wqe->ctrl ) );
793         MLX_FILL_1 ( &wqe->ctrl, 0, always1, 1 );
794         memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
795         MLX_FILL_2 ( &wqe->ud, 0,
796                      ud_address_vector.pd, ARBEL_GLOBAL_PD,
797                      ud_address_vector.port_number, PXE_IB_PORT );
798         MLX_FILL_2 ( &wqe->ud, 1,
799                      ud_address_vector.rlid, av->dlid,
800                      ud_address_vector.g, av->gid_present );
801         MLX_FILL_2 ( &wqe->ud, 2,
802                      ud_address_vector.max_stat_rate,
803                          ( ( av->rate >= 3 ) ? 0 : 1 ),
804                      ud_address_vector.msg, 3 );
805         MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
806         gid = ( av->gid_present ? &av->gid : &arbel_no_gid );
807         memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) );
808         MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->dest_qp );
809         MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
810         MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
811         MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
812         MLX_FILL_1 ( &wqe->data[0], 3,
813                      local_address_l, virt_to_bus ( iobuf->data ) );
814
815         /* Update previous work queue entry's "next" field */
816         nds = ( ( offsetof ( typeof ( *wqe ), data ) +
817                   sizeof ( wqe->data[0] ) ) >> 4 );
818         MLX_SET ( &prev_wqe->next, nopcode, ARBEL_OPCODE_SEND );
819         MLX_FILL_3 ( &prev_wqe->next, 1,
820                      nds, nds,
821                      f, 1,
822                      always1, 1 );
823
824         /* Update doorbell record */
825         barrier();
826         qp_db_rec = &arbel->db_rec[arbel_send_wq->doorbell_idx].qp;
827         MLX_FILL_1 ( qp_db_rec, 0,
828                      counter, ( ( wq->next_idx + 1 ) & 0xffff ) );
829
830         /* Ring doorbell register */
831         MLX_FILL_4 ( &db_reg.send, 0,
832                      nopcode, ARBEL_OPCODE_SEND,
833                      f, 1,
834                      wqe_counter, ( wq->next_idx & 0xffff ),
835                      wqe_cnt, 1 );
836         MLX_FILL_2 ( &db_reg.send, 1,
837                      nds, nds,
838                      qpn, qp->qpn );
839         arbel_ring_doorbell ( arbel, &db_reg, POST_SND_OFFSET );
840
841         /* Update work queue's index */
842         wq->next_idx++;
843
844         return 0;
845 }
846
847 /**
848  * Post receive work queue entry
849  *
850  * @v ibdev             Infiniband device
851  * @v qp                Queue pair
852  * @v iobuf             I/O buffer
853  * @ret rc              Return status code
854  */
855 static int arbel_post_recv ( struct ib_device *ibdev,
856                              struct ib_queue_pair *qp,
857                              struct io_buffer *iobuf ) {
858         struct arbel *arbel = ibdev->dev_priv;
859         struct arbel_queue_pair *arbel_qp = qp->dev_priv;
860         struct ib_work_queue *wq = &qp->recv;
861         struct arbel_recv_work_queue *arbel_recv_wq = &arbel_qp->recv;
862         struct arbelprm_recv_wqe *wqe;
863         union arbelprm_doorbell_record *db_rec;
864         unsigned int wqe_idx_mask;
865
866         /* Allocate work queue entry */
867         wqe_idx_mask = ( wq->num_wqes - 1 );
868         if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
869                 DBGC ( arbel, "Arbel %p receive queue full", arbel );
870                 return -ENOBUFS;
871         }
872         wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
873         wqe = &arbel_recv_wq->wqe[wq->next_idx & wqe_idx_mask].recv;
874
875         /* Construct work queue entry */
876         MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
877         MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
878         MLX_FILL_1 ( &wqe->data[0], 3,
879                      local_address_l, virt_to_bus ( iobuf->data ) );
880
881         /* Update doorbell record */
882         barrier();
883         db_rec = &arbel->db_rec[arbel_recv_wq->doorbell_idx];
884         MLX_FILL_1 ( &db_rec->qp, 0,
885                      counter, ( ( wq->next_idx + 1 ) & 0xffff ) );      
886
887         /* Update work queue's index */
888         wq->next_idx++;
889
890         return 0;       
891 }
892
893 /**
894  * Handle completion
895  *
896  * @v ibdev             Infiniband device
897  * @v cq                Completion queue
898  * @v cqe               Hardware completion queue entry
899  * @v complete_send     Send completion handler
900  * @v complete_recv     Receive completion handler
901  * @ret rc              Return status code
902  */
903 static int arbel_complete ( struct ib_device *ibdev,
904                             struct ib_completion_queue *cq,
905                             union arbelprm_completion_entry *cqe,
906                             ib_completer_t complete_send,
907                             ib_completer_t complete_recv ) {
908         struct arbel *arbel = ibdev->dev_priv;
909         struct ib_completion completion;
910         struct ib_work_queue *wq;
911         struct ib_queue_pair *qp;
912         struct arbel_queue_pair *arbel_qp;
913         struct arbel_send_work_queue *arbel_send_wq;
914         struct arbel_recv_work_queue *arbel_recv_wq;
915         struct io_buffer *iobuf;
916         ib_completer_t complete;
917         unsigned int opcode;
918         unsigned long qpn;
919         int is_send;
920         unsigned long wqe_adr;
921         unsigned int wqe_idx;
922         int rc = 0;
923
924         /* Parse completion */
925         memset ( &completion, 0, sizeof ( completion ) );
926         completion.len = MLX_GET ( &cqe->normal, byte_cnt );
927         qpn = MLX_GET ( &cqe->normal, my_qpn );
928         is_send = MLX_GET ( &cqe->normal, s );
929         wqe_adr = ( MLX_GET ( &cqe->normal, wqe_adr ) << 6 );
930         opcode = MLX_GET ( &cqe->normal, opcode );
931         if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) {
932                 /* "s" field is not valid for error opcodes */
933                 is_send = ( opcode == ARBEL_OPCODE_SEND_ERROR );
934                 completion.syndrome = MLX_GET ( &cqe->error, syndrome );
935                 DBGC ( arbel, "Arbel %p CPN %lx syndrome %x vendor %lx\n",
936                        arbel, cq->cqn, completion.syndrome,
937                        MLX_GET ( &cqe->error, vendor_code ) );
938                 rc = -EIO;
939                 /* Don't return immediately; propagate error to completer */
940         }
941
942         /* Identify work queue */
943         wq = ib_find_wq ( cq, qpn, is_send );
944         if ( ! wq ) {
945                 DBGC ( arbel, "Arbel %p CQN %lx unknown %s QPN %lx\n",
946                        arbel, cq->cqn, ( is_send ? "send" : "recv" ), qpn );
947                 return -EIO;
948         }
949         qp = wq->qp;
950         arbel_qp = qp->dev_priv;
951
952         /* Identify work queue entry index */
953         if ( is_send ) {
954                 arbel_send_wq = &arbel_qp->send;
955                 wqe_idx = ( ( wqe_adr - virt_to_bus ( arbel_send_wq->wqe ) ) /
956                             sizeof ( arbel_send_wq->wqe[0] ) );
957         } else {
958                 arbel_recv_wq = &arbel_qp->recv;
959                 wqe_idx = ( ( wqe_adr - virt_to_bus ( arbel_recv_wq->wqe ) ) /
960                             sizeof ( arbel_recv_wq->wqe[0] ) );
961         }
962
963         /* Identify I/O buffer */
964         iobuf = wq->iobufs[wqe_idx];
965         if ( ! iobuf ) {
966                 DBGC ( arbel, "Arbel %p CQN %lx QPN %lx empty WQE %x\n",
967                        arbel, cq->cqn, qpn, wqe_idx );
968                 return -EIO;
969         }
970         wq->iobufs[wqe_idx] = NULL;
971
972         /* Pass off to caller's completion handler */
973         complete = ( is_send ? complete_send : complete_recv );
974         complete ( ibdev, qp, &completion, iobuf );
975
976         return rc;
977 }                            
978
979 /**
980  * Drain event queue
981  *
982  * @v arbel             Arbel device
983  */
984 static void arbel_drain_eq ( struct arbel *arbel ) {
985 #warning "drain the event queue"
986 }
987
988 /**
989  * Poll completion queue
990  *
991  * @v ibdev             Infiniband device
992  * @v cq                Completion queue
993  * @v complete_send     Send completion handler
994  * @v complete_recv     Receive completion handler
995  */
996 static void arbel_poll_cq ( struct ib_device *ibdev,
997                             struct ib_completion_queue *cq,
998                             ib_completer_t complete_send,
999                             ib_completer_t complete_recv ) {
1000         struct arbel *arbel = ibdev->dev_priv;
1001         struct arbel_completion_queue *arbel_cq = cq->dev_priv;
1002         struct arbelprm_cq_ci_db_record *ci_db_rec;
1003         union arbelprm_completion_entry *cqe;
1004         unsigned int cqe_idx_mask;
1005         int rc;
1006
1007         /* Drain the event queue */
1008         arbel_drain_eq ( arbel );
1009
1010         while ( 1 ) {
1011                 /* Look for completion entry */
1012                 cqe_idx_mask = ( cq->num_cqes - 1 );
1013                 cqe = &arbel_cq->cqe[cq->next_idx & cqe_idx_mask];
1014                 if ( MLX_GET ( &cqe->normal, owner ) != 0 ) {
1015                         /* Entry still owned by hardware; end of poll */
1016                         break;
1017                 }
1018
1019                 /* Handle completion */
1020                 if ( ( rc = arbel_complete ( ibdev, cq, cqe, complete_send,
1021                                              complete_recv ) ) != 0 ) {
1022                         DBGC ( arbel, "Arbel %p failed to complete: %s\n",
1023                                arbel, strerror ( rc ) );
1024                         DBGC_HD ( arbel, cqe, sizeof ( *cqe ) );
1025                 }
1026
1027                 /* Return ownership to hardware */
1028                 MLX_FILL_1 ( &cqe->normal, 7, owner, 1 );
1029                 barrier();
1030                 /* Update completion queue's index */
1031                 cq->next_idx++;
1032                 /* Update doorbell record */
1033                 ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
1034                 MLX_FILL_1 ( ci_db_rec, 0,
1035                              counter, ( cq->next_idx & 0xffffffffUL ) );
1036         }
1037 }
1038
1039 /***************************************************************************
1040  *
1041  * Multicast group operations
1042  *
1043  ***************************************************************************
1044  */
1045
1046 /**
1047  * Attach to multicast group
1048  *
1049  * @v ibdev             Infiniband device
1050  * @v qp                Queue pair
1051  * @v gid               Multicast GID
1052  * @ret rc              Return status code
1053  */
1054 static int arbel_mcast_attach ( struct ib_device *ibdev,
1055                                 struct ib_queue_pair *qp,
1056                                 struct ib_gid *gid ) {
1057         struct arbel *arbel = ibdev->dev_priv;
1058         struct arbelprm_mgm_hash hash;
1059         struct arbelprm_mgm_entry mgm;
1060         unsigned int index;
1061         int rc;
1062
1063         /* Generate hash table index */
1064         if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
1065                 DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
1066                        arbel, strerror ( rc ) );
1067                 return rc;
1068         }
1069         index = MLX_GET ( &hash, hash );
1070
1071         /* Check for existing hash table entry */
1072         if ( ( rc = arbel_cmd_read_mgm ( arbel, index, &mgm ) ) != 0 ) {
1073                 DBGC ( arbel, "Arbel %p could not read MGM %#x: %s\n",
1074                        arbel, index, strerror ( rc ) );
1075                 return rc;
1076         }
1077         if ( MLX_GET ( &mgm, mgmqp_0.qi ) != 0 ) {
1078                 /* FIXME: this implementation allows only a single QP
1079                  * per multicast group, and doesn't handle hash
1080                  * collisions.  Sufficient for IPoIB but may need to
1081                  * be extended in future.
1082                  */
1083                 DBGC ( arbel, "Arbel %p MGID index %#x already in use\n",
1084                        arbel, index );
1085                 return -EBUSY;
1086         }
1087
1088         /* Update hash table entry */
1089         MLX_FILL_2 ( &mgm, 8,
1090                      mgmqp_0.qpn_i, qp->qpn,
1091                      mgmqp_0.qi, 1 );
1092         memcpy ( &mgm.u.dwords[4], gid, sizeof ( *gid ) );
1093         if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
1094                 DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
1095                        arbel, index, strerror ( rc ) );
1096                 return rc;
1097         }
1098
1099         return 0;
1100 }
1101
1102 /**
1103  * Detach from multicast group
1104  *
1105  * @v ibdev             Infiniband device
1106  * @v qp                Queue pair
1107  * @v gid               Multicast GID
1108  */
1109 static void arbel_mcast_detach ( struct ib_device *ibdev,
1110                                  struct ib_queue_pair *qp __unused,
1111                                  struct ib_gid *gid ) {
1112         struct arbel *arbel = ibdev->dev_priv;
1113         struct arbelprm_mgm_hash hash;
1114         struct arbelprm_mgm_entry mgm;
1115         unsigned int index;
1116         int rc;
1117
1118         /* Generate hash table index */
1119         if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
1120                 DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
1121                        arbel, strerror ( rc ) );
1122                 return;
1123         }
1124         index = MLX_GET ( &hash, hash );
1125
1126         /* Clear hash table entry */
1127         memset ( &mgm, 0, sizeof ( mgm ) );
1128         if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
1129                 DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
1130                        arbel, index, strerror ( rc ) );
1131                 return;
1132         }
1133 }
1134
1135 /** Arbel Infiniband operations */
1136 static struct ib_device_operations arbel_ib_operations = {
1137         .create_cq      = arbel_create_cq,
1138         .destroy_cq     = arbel_destroy_cq,
1139         .create_qp      = arbel_create_qp,
1140         .destroy_qp     = arbel_destroy_qp,
1141         .post_send      = arbel_post_send,
1142         .post_recv      = arbel_post_recv,
1143         .poll_cq        = arbel_poll_cq,
1144         .mcast_attach   = arbel_mcast_attach,
1145         .mcast_detach   = arbel_mcast_detach,
1146 };
1147
1148
1149 static int arbel_mad_ifc ( struct arbel *arbel,
1150                            union arbelprm_mad *mad ) {
1151         struct ib_mad_hdr *hdr = &mad->mad.mad_hdr;
1152         int rc;
1153
1154         hdr->base_version = IB_MGMT_BASE_VERSION;
1155         if ( ( rc = arbel_cmd_mad_ifc ( arbel, mad ) ) != 0 ) {
1156                 DBGC ( arbel, "Arbel %p could not issue MAD IFC: %s\n",
1157                        arbel, strerror ( rc ) );
1158                 return rc;
1159         }
1160         if ( hdr->status != 0 ) {
1161                 DBGC ( arbel, "Arbel %p MAD IFC status %04x\n",
1162                        arbel, ntohs ( hdr->status ) );
1163                 return -EIO;
1164         }
1165         return 0;
1166 }
1167
1168 static int arbel_get_port_info ( struct arbel *arbel,
1169                                  struct ib_mad_port_info *port_info ) {
1170         union arbelprm_mad mad;
1171         struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1172         int rc;
1173
1174         memset ( &mad, 0, sizeof ( mad ) );
1175         hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1176         hdr->class_version = 1;
1177         hdr->method = IB_MGMT_METHOD_GET;
1178         hdr->attr_id = htons ( IB_SMP_ATTR_PORT_INFO );
1179         hdr->attr_mod = htonl ( PXE_IB_PORT );
1180         if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1181                 DBGC ( arbel, "Arbel %p could not get port info: %s\n",
1182                        arbel, strerror ( rc ) );
1183                 return rc;
1184         }
1185         memcpy ( port_info, &mad.mad.port_info, sizeof ( *port_info ) );
1186         return 0;
1187 }
1188
1189 static int arbel_get_guid_info ( struct arbel *arbel,
1190                                  struct ib_mad_guid_info *guid_info ) {
1191         union arbelprm_mad mad;
1192         struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1193         int rc;
1194
1195         memset ( &mad, 0, sizeof ( mad ) );
1196         hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1197         hdr->class_version = 1;
1198         hdr->method = IB_MGMT_METHOD_GET;
1199         hdr->attr_id = htons ( IB_SMP_ATTR_GUID_INFO );
1200         if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1201                 DBGC ( arbel, "Arbel %p could not get GUID info: %s\n",
1202                        arbel, strerror ( rc ) );
1203                 return rc;
1204         }
1205         memcpy ( guid_info, &mad.mad.guid_info, sizeof ( *guid_info ) );
1206         return 0;
1207 }
1208
1209 static int arbel_get_pkey_table ( struct arbel *arbel,
1210                                   struct ib_mad_pkey_table *pkey_table ) {
1211         union arbelprm_mad mad;
1212         struct ib_mad_hdr *hdr = &mad.mad.mad_hdr;
1213         int rc;
1214
1215         memset ( &mad, 0, sizeof ( mad ) );
1216         hdr->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED;
1217         hdr->class_version = 1;
1218         hdr->method = IB_MGMT_METHOD_GET;
1219         hdr->attr_id = htons ( IB_SMP_ATTR_PKEY_TABLE );
1220         if ( ( rc = arbel_mad_ifc ( arbel, &mad ) ) != 0 ) {
1221                 DBGC ( arbel, "Arbel %p could not get pkey table: %s\n",
1222                        arbel, strerror ( rc ) );
1223                 return rc;
1224         }
1225         memcpy ( pkey_table, &mad.mad.pkey_table, sizeof ( *pkey_table ) );
1226         return 0;
1227 }
1228
1229 static int arbel_get_port_gid ( struct arbel *arbel,
1230                                 struct ib_gid *port_gid ) {
1231         union {
1232                 /* This union exists just to save stack space */
1233                 struct ib_mad_port_info port_info;
1234                 struct ib_mad_guid_info guid_info;
1235         } u;
1236         int rc;
1237
1238         /* Port info gives us the first half of the port GID */
1239         if ( ( rc = arbel_get_port_info ( arbel, &u.port_info ) ) != 0 )
1240                 return rc;
1241         memcpy ( &port_gid->bytes[0], u.port_info.gid_prefix, 8 );
1242
1243         /* GUID info gives us the second half of the port GID */
1244         if ( ( rc = arbel_get_guid_info ( arbel, &u.guid_info ) ) != 0 )
1245                 return rc;
1246         memcpy ( &port_gid->bytes[8], u.guid_info.gid_local, 8 );
1247
1248         return 0;
1249 }
1250
1251 static int arbel_get_broadcast_gid ( struct arbel *arbel,
1252                                      struct ib_gid *broadcast_gid ) {
1253         static const struct ib_gid ipv4_broadcast_gid = {
1254                 { 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
1255                   0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff }
1256         };
1257         struct ib_mad_pkey_table pkey_table;
1258         int rc;
1259
1260         /* Start with the IPv4 broadcast GID */
1261         memcpy ( broadcast_gid, &ipv4_broadcast_gid,
1262                  sizeof ( *broadcast_gid ) );
1263
1264         /* Add partition key */
1265         if ( ( rc = arbel_get_pkey_table ( arbel, &pkey_table ) ) != 0 )
1266                 return rc;
1267         memcpy ( &broadcast_gid->bytes[4], &pkey_table.pkey[0][0],
1268                  sizeof ( pkey_table.pkey[0][0] ) );
1269
1270         return 0;
1271 }
1272
1273 /**
1274  * Probe PCI device
1275  *
1276  * @v pci               PCI device
1277  * @v id                PCI ID
1278  * @ret rc              Return status code
1279  */
1280 static int arbel_probe ( struct pci_device *pci,
1281                          const struct pci_device_id *id __unused ) {
1282         struct ib_device *ibdev;
1283         struct arbelprm_query_dev_lim dev_lim;
1284         struct arbel *arbel;
1285         udqp_t qph;
1286         int rc;
1287
1288         /* Allocate Infiniband device */
1289         ibdev = alloc_ibdev ( sizeof ( *arbel ) );
1290         if ( ! ibdev )
1291                 return -ENOMEM;
1292         ibdev->op = &arbel_ib_operations;
1293         pci_set_drvdata ( pci, ibdev );
1294         ibdev->dev = &pci->dev;
1295         arbel = ibdev->dev_priv;
1296         memset ( arbel, 0, sizeof ( *arbel ) );
1297
1298         /* Fix up PCI device */
1299         adjust_pci_device ( pci );
1300
1301         /* Initialise hardware */
1302         if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
1303                 goto err_ib_driver_init;
1304
1305         /* Hack up IB structures */
1306         arbel->config = memfree_pci_dev.cr_space;
1307         arbel->mailbox_in = dev_buffers_p->inprm_buf;
1308         arbel->mailbox_out = dev_buffers_p->outprm_buf;
1309         arbel->uar = memfree_pci_dev.uar;
1310         arbel->db_rec = dev_ib_data.uar_context_base;
1311         arbel->reserved_lkey = dev_ib_data.mkey;
1312         arbel->eqn = dev_ib_data.eq.eqn;
1313
1314         /* Get device limits */
1315         if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
1316                 DBGC ( arbel, "Arbel %p could not get device limits: %s\n",
1317                        arbel, strerror ( rc ) );
1318                 goto err_query_dev_lim;
1319         }
1320         arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
1321         arbel->limits.reserved_cqs =
1322                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
1323         arbel->limits.reserved_qps =
1324                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_qps ) );
1325
1326         /* Get port GID */
1327         if ( ( rc = arbel_get_port_gid ( arbel, &ibdev->port_gid ) ) != 0 ) {
1328                 DBGC ( arbel, "Arbel %p could not determine port GID: %s\n",
1329                        arbel, strerror ( rc ) );
1330                 goto err_get_port_gid;
1331         }
1332
1333         /* Get broadcast GID */
1334         if ( ( rc = arbel_get_broadcast_gid ( arbel,
1335                                               &ibdev->broadcast_gid ) ) != 0 ){
1336                 DBGC ( arbel, "Arbel %p could not determine broadcast GID: "
1337                        "%s\n", arbel, strerror ( rc ) );
1338                 goto err_get_broadcast_gid;
1339         }
1340
1341         struct ud_av_st *bcast_av = ib_data.bcast_av;
1342         struct arbelprm_ud_address_vector *bav =
1343                 ( struct arbelprm_ud_address_vector * ) &bcast_av->av;
1344         struct ib_address_vector *av = &hack_ipoib_bcast_av;
1345         av->dest_qp = bcast_av->dest_qp;
1346         av->qkey = bcast_av->qkey;
1347         av->dlid = MLX_GET ( bav, rlid );
1348         av->rate = ( MLX_GET ( bav, max_stat_rate ) ? 1 : 4 );
1349         av->sl = MLX_GET ( bav, sl );
1350         av->gid_present = 1;
1351         memcpy ( &av->gid, ( ( void * ) bav ) + 16, 16 );
1352
1353         /* Add IPoIB device */
1354         if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
1355                 DBGC ( arbel, "Arbel %p could not add IPoIB device: %s\n",
1356                        arbel, strerror ( rc ) );
1357                 goto err_ipoib_probe;
1358         }
1359
1360         return 0;
1361
1362  err_ipoib_probe:
1363  err_get_broadcast_gid:
1364  err_get_port_gid:
1365  err_query_dev_lim:
1366         ib_driver_close ( 0 );
1367  err_ib_driver_init:
1368         free_ibdev ( ibdev );
1369         return rc;
1370 }
1371
1372 /**
1373  * Remove PCI device
1374  *
1375  * @v pci               PCI device
1376  */
1377 static void arbel_remove ( struct pci_device *pci ) {
1378         struct ib_device *ibdev = pci_get_drvdata ( pci );
1379
1380         ipoib_remove ( ibdev );
1381         ib_driver_close ( 0 );
1382 }
1383
1384 static struct pci_device_id arbel_nics[] = {
1385         PCI_ROM ( 0x15b3, 0x6282, "MT25218", "MT25218 HCA driver" ),
1386         PCI_ROM ( 0x15b3, 0x6274, "MT25204", "MT25204 HCA driver" ),
1387 };
1388
1389 struct pci_driver arbel_driver __pci_driver = {
1390         .ids = arbel_nics,
1391         .id_count = ( sizeof ( arbel_nics ) / sizeof ( arbel_nics[0] ) ),
1392         .probe = arbel_probe,
1393         .remove = arbel_remove,
1394 };