[pxe] Avoid potential interrupt storms when using shared interrupts
[people/mcb30/gpxe.git] / src / drivers / infiniband / arbel.c
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * Based in part upon the original driver by Mellanox Technologies
5  * Ltd.  Portions may be Copyright (c) Mellanox Technologies Ltd.
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 of the
10  * License, or any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 FILE_LICENCE ( GPL2_OR_LATER );
23
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <strings.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <byteswap.h>
32 #include <gpxe/io.h>
33 #include <gpxe/pci.h>
34 #include <gpxe/malloc.h>
35 #include <gpxe/umalloc.h>
36 #include <gpxe/iobuf.h>
37 #include <gpxe/netdevice.h>
38 #include <gpxe/infiniband.h>
39 #include <gpxe/ib_smc.h>
40 #include "arbel.h"
41
42 /**
43  * @file
44  *
45  * Mellanox Arbel Infiniband HCA
46  *
47  */
48
49 /***************************************************************************
50  *
51  * Queue number allocation
52  *
53  ***************************************************************************
54  */
55
56 /**
57  * Allocate queue number
58  *
59  * @v q_inuse           Queue usage bitmask
60  * @v max_inuse         Maximum number of in-use queues
61  * @ret qn_offset       Free queue number offset, or negative error
62  */
63 static int arbel_alloc_qn_offset ( arbel_bitmask_t *q_inuse,
64                                    unsigned int max_inuse ) {
65         unsigned int qn_offset = 0;
66         arbel_bitmask_t mask = 1;
67
68         while ( qn_offset < max_inuse ) {
69                 if ( ( mask & *q_inuse ) == 0 ) {
70                         *q_inuse |= mask;
71                         return qn_offset;
72                 }
73                 qn_offset++;
74                 mask <<= 1;
75                 if ( ! mask ) {
76                         mask = 1;
77                         q_inuse++;
78                 }
79         }
80         return -ENFILE;
81 }
82
83 /**
84  * Free queue number
85  *
86  * @v q_inuse           Queue usage bitmask
87  * @v qn_offset         Queue number offset
88  */
89 static void arbel_free_qn_offset ( arbel_bitmask_t *q_inuse, int qn_offset ) {
90         arbel_bitmask_t mask;
91
92         mask = ( 1 << ( qn_offset % ( 8 * sizeof ( mask ) ) ) );
93         q_inuse += ( qn_offset / ( 8 * sizeof ( mask ) ) );
94         *q_inuse &= ~mask;
95 }
96
97 /***************************************************************************
98  *
99  * HCA commands
100  *
101  ***************************************************************************
102  */
103
104 /**
105  * Wait for Arbel command completion
106  *
107  * @v arbel             Arbel device
108  * @ret rc              Return status code
109  */
110 static int arbel_cmd_wait ( struct arbel *arbel,
111                             struct arbelprm_hca_command_register *hcr ) {
112         unsigned int wait;
113
114         for ( wait = ARBEL_HCR_MAX_WAIT_MS ; wait ; wait-- ) {
115                 hcr->u.dwords[6] =
116                         readl ( arbel->config + ARBEL_HCR_REG ( 6 ) );
117                 if ( MLX_GET ( hcr, go ) == 0 )
118                         return 0;
119                 mdelay ( 1 );
120         }
121         return -EBUSY;
122 }
123
124 /**
125  * Issue HCA command
126  *
127  * @v arbel             Arbel device
128  * @v command           Command opcode, flags and input/output lengths
129  * @v op_mod            Opcode modifier (0 if no modifier applicable)
130  * @v in                Input parameters
131  * @v in_mod            Input modifier (0 if no modifier applicable)
132  * @v out               Output parameters
133  * @ret rc              Return status code
134  */
135 static int arbel_cmd ( struct arbel *arbel, unsigned long command,
136                        unsigned int op_mod, const void *in,
137                        unsigned int in_mod, void *out ) {
138         struct arbelprm_hca_command_register hcr;
139         unsigned int opcode = ARBEL_HCR_OPCODE ( command );
140         size_t in_len = ARBEL_HCR_IN_LEN ( command );
141         size_t out_len = ARBEL_HCR_OUT_LEN ( command );
142         void *in_buffer;
143         void *out_buffer;
144         unsigned int status;
145         unsigned int i;
146         int rc;
147
148         assert ( in_len <= ARBEL_MBOX_SIZE );
149         assert ( out_len <= ARBEL_MBOX_SIZE );
150
151         DBGC2 ( arbel, "Arbel %p command %02x in %zx%s out %zx%s\n",
152                 arbel, opcode, in_len,
153                 ( ( command & ARBEL_HCR_IN_MBOX ) ? "(mbox)" : "" ), out_len,
154                 ( ( command & ARBEL_HCR_OUT_MBOX ) ? "(mbox)" : "" ) );
155
156         /* Check that HCR is free */
157         if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
158                 DBGC ( arbel, "Arbel %p command interface locked\n", arbel );
159                 return rc;
160         }
161
162         /* Prepare HCR */
163         memset ( &hcr, 0, sizeof ( hcr ) );
164         in_buffer = &hcr.u.dwords[0];
165         if ( in_len && ( command & ARBEL_HCR_IN_MBOX ) ) {
166                 in_buffer = arbel->mailbox_in;
167                 MLX_FILL_1 ( &hcr, 1, in_param_l, virt_to_bus ( in_buffer ) );
168         }
169         memcpy ( in_buffer, in, in_len );
170         MLX_FILL_1 ( &hcr, 2, input_modifier, in_mod );
171         out_buffer = &hcr.u.dwords[3];
172         if ( out_len && ( command & ARBEL_HCR_OUT_MBOX ) ) {
173                 out_buffer = arbel->mailbox_out;
174                 MLX_FILL_1 ( &hcr, 4, out_param_l,
175                              virt_to_bus ( out_buffer ) );
176         }
177         MLX_FILL_3 ( &hcr, 6,
178                      opcode, opcode,
179                      opcode_modifier, op_mod,
180                      go, 1 );
181         DBGC2_HD ( arbel, &hcr, sizeof ( hcr ) );
182         if ( in_len ) {
183                 DBGC2 ( arbel, "Input:\n" );
184                 DBGC2_HD ( arbel, in, ( ( in_len < 512 ) ? in_len : 512 ) );
185         }
186
187         /* Issue command */
188         for ( i = 0 ; i < ( sizeof ( hcr ) / sizeof ( hcr.u.dwords[0] ) ) ;
189               i++ ) {
190                 writel ( hcr.u.dwords[i],
191                          arbel->config + ARBEL_HCR_REG ( i ) );
192                 barrier();
193         }
194
195         /* Wait for command completion */
196         if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
197                 DBGC ( arbel, "Arbel %p timed out waiting for command:\n",
198                        arbel );
199                 DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
200                 return rc;
201         }
202
203         /* Check command status */
204         status = MLX_GET ( &hcr, status );
205         if ( status != 0 ) {
206                 DBGC ( arbel, "Arbel %p command failed with status %02x:\n",
207                        arbel, status );
208                 DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
209                 return -EIO;
210         }
211
212         /* Read output parameters, if any */
213         hcr.u.dwords[3] = readl ( arbel->config + ARBEL_HCR_REG ( 3 ) );
214         hcr.u.dwords[4] = readl ( arbel->config + ARBEL_HCR_REG ( 4 ) );
215         memcpy ( out, out_buffer, out_len );
216         if ( out_len ) {
217                 DBGC2 ( arbel, "Output:\n" );
218                 DBGC2_HD ( arbel, out, ( ( out_len < 512 ) ? out_len : 512 ) );
219         }
220
221         return 0;
222 }
223
224 static inline int
225 arbel_cmd_query_dev_lim ( struct arbel *arbel,
226                           struct arbelprm_query_dev_lim *dev_lim ) {
227         return arbel_cmd ( arbel,
228                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_QUERY_DEV_LIM,
229                                                1, sizeof ( *dev_lim ) ),
230                            0, NULL, 0, dev_lim );
231 }
232
233 static inline int
234 arbel_cmd_query_fw ( struct arbel *arbel, struct arbelprm_query_fw *fw ) {
235         return arbel_cmd ( arbel,
236                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_QUERY_FW, 
237                                                1, sizeof ( *fw ) ),
238                            0, NULL, 0, fw );
239 }
240
241 static inline int
242 arbel_cmd_init_hca ( struct arbel *arbel,
243                      const struct arbelprm_init_hca *init_hca ) {
244         return arbel_cmd ( arbel,
245                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_INIT_HCA,
246                                               1, sizeof ( *init_hca ) ),
247                            0, init_hca, 0, NULL );
248 }
249
250 static inline int
251 arbel_cmd_close_hca ( struct arbel *arbel ) {
252         return arbel_cmd ( arbel,
253                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_CLOSE_HCA ),
254                            0, NULL, 0, NULL );
255 }
256
257 static inline int
258 arbel_cmd_init_ib ( struct arbel *arbel, unsigned int port,
259                     const struct arbelprm_init_ib *init_ib ) {
260         return arbel_cmd ( arbel,
261                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_INIT_IB,
262                                               1, sizeof ( *init_ib ) ),
263                            0, init_ib, port, NULL );
264 }
265
266 static inline int
267 arbel_cmd_close_ib ( struct arbel *arbel, unsigned int port ) {
268         return arbel_cmd ( arbel,
269                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_CLOSE_IB ),
270                            0, NULL, port, NULL );
271 }
272
273 static inline int
274 arbel_cmd_sw2hw_mpt ( struct arbel *arbel, unsigned int index,
275                       const struct arbelprm_mpt *mpt ) {
276         return arbel_cmd ( arbel,
277                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_SW2HW_MPT,
278                                               1, sizeof ( *mpt ) ),
279                            0, mpt, index, NULL );
280 }
281
282 static inline int
283 arbel_cmd_map_eq ( struct arbel *arbel, unsigned long index_map,
284                    const struct arbelprm_event_mask *mask ) {
285         return arbel_cmd ( arbel,
286                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_MAP_EQ,
287                                               0, sizeof ( *mask ) ),
288                            0, mask, index_map, NULL );
289 }
290
291 static inline int
292 arbel_cmd_sw2hw_eq ( struct arbel *arbel, unsigned int index,
293                      const struct arbelprm_eqc *eqctx ) {
294         return arbel_cmd ( arbel,
295                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_SW2HW_EQ,
296                                               1, sizeof ( *eqctx ) ),
297                            0, eqctx, index, NULL );
298 }
299
300 static inline int
301 arbel_cmd_hw2sw_eq ( struct arbel *arbel, unsigned int index,
302                      struct arbelprm_eqc *eqctx ) {
303         return arbel_cmd ( arbel,
304                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_HW2SW_EQ,
305                                                1, sizeof ( *eqctx ) ),
306                            1, NULL, index, eqctx );
307 }
308
309 static inline int
310 arbel_cmd_sw2hw_cq ( struct arbel *arbel, unsigned long cqn,
311                      const struct arbelprm_completion_queue_context *cqctx ) {
312         return arbel_cmd ( arbel,
313                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_SW2HW_CQ,
314                                               1, sizeof ( *cqctx ) ),
315                            0, cqctx, cqn, NULL );
316 }
317
318 static inline int
319 arbel_cmd_hw2sw_cq ( struct arbel *arbel, unsigned long cqn,
320                      struct arbelprm_completion_queue_context *cqctx) {
321         return arbel_cmd ( arbel,
322                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_HW2SW_CQ,
323                                                1, sizeof ( *cqctx ) ),
324                            0, NULL, cqn, cqctx );
325 }
326
327 static inline int
328 arbel_cmd_rst2init_qpee ( struct arbel *arbel, unsigned long qpn,
329                           const struct arbelprm_qp_ee_state_transitions *ctx ){
330         return arbel_cmd ( arbel,
331                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_RST2INIT_QPEE,
332                                               1, sizeof ( *ctx ) ),
333                            0, ctx, qpn, NULL );
334 }
335
336 static inline int
337 arbel_cmd_init2rtr_qpee ( struct arbel *arbel, unsigned long qpn,
338                           const struct arbelprm_qp_ee_state_transitions *ctx ){
339         return arbel_cmd ( arbel,
340                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_INIT2RTR_QPEE,
341                                               1, sizeof ( *ctx ) ),
342                            0, ctx, qpn, NULL );
343 }
344
345 static inline int
346 arbel_cmd_rtr2rts_qpee ( struct arbel *arbel, unsigned long qpn,
347                          const struct arbelprm_qp_ee_state_transitions *ctx ) {
348         return arbel_cmd ( arbel,
349                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_RTR2RTS_QPEE,
350                                               1, sizeof ( *ctx ) ),
351                            0, ctx, qpn, NULL );
352 }
353
354 static inline int
355 arbel_cmd_rts2rts_qp ( struct arbel *arbel, unsigned long qpn,
356                        const struct arbelprm_qp_ee_state_transitions *ctx ) {
357         return arbel_cmd ( arbel,
358                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_RTS2RTS_QPEE,
359                                               1, sizeof ( *ctx ) ),
360                            0, ctx, qpn, NULL );
361 }
362
363 static inline int
364 arbel_cmd_2rst_qpee ( struct arbel *arbel, unsigned long qpn ) {
365         return arbel_cmd ( arbel,
366                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_2RST_QPEE ),
367                            0x03, NULL, qpn, NULL );
368 }
369
370 static inline int
371 arbel_cmd_mad_ifc ( struct arbel *arbel, unsigned int port,
372                     union arbelprm_mad *mad ) {
373         return arbel_cmd ( arbel,
374                            ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MAD_IFC,
375                                                  1, sizeof ( *mad ),
376                                                  1, sizeof ( *mad ) ),
377                            0x03, mad, port, mad );
378 }
379
380 static inline int
381 arbel_cmd_read_mgm ( struct arbel *arbel, unsigned int index,
382                      struct arbelprm_mgm_entry *mgm ) {
383         return arbel_cmd ( arbel,
384                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_READ_MGM,
385                                                1, sizeof ( *mgm ) ),
386                            0, NULL, index, mgm );
387 }
388
389 static inline int
390 arbel_cmd_write_mgm ( struct arbel *arbel, unsigned int index,
391                       const struct arbelprm_mgm_entry *mgm ) {
392         return arbel_cmd ( arbel,
393                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_WRITE_MGM,
394                                               1, sizeof ( *mgm ) ),
395                            0, mgm, index, NULL );
396 }
397
398 static inline int
399 arbel_cmd_mgid_hash ( struct arbel *arbel, const struct ib_gid *gid,
400                       struct arbelprm_mgm_hash *hash ) {
401         return arbel_cmd ( arbel,
402                            ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_MGID_HASH,
403                                                  1, sizeof ( *gid ),
404                                                  0, sizeof ( *hash ) ),
405                            0, gid, 0, hash );
406 }
407
408 static inline int
409 arbel_cmd_run_fw ( struct arbel *arbel ) {
410         return arbel_cmd ( arbel,
411                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_RUN_FW ),
412                            0, NULL, 0, NULL );
413 }
414
415 static inline int
416 arbel_cmd_disable_lam ( struct arbel *arbel ) {
417         return arbel_cmd ( arbel,
418                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_DISABLE_LAM ),
419                            0, NULL, 0, NULL );
420 }
421
422 static inline int
423 arbel_cmd_enable_lam ( struct arbel *arbel, struct arbelprm_access_lam *lam ) {
424         return arbel_cmd ( arbel,
425                            ARBEL_HCR_OUT_CMD ( ARBEL_HCR_ENABLE_LAM,
426                                                1, sizeof ( *lam ) ),
427                            1, NULL, 0, lam );
428 }
429
430 static inline int
431 arbel_cmd_unmap_icm ( struct arbel *arbel, unsigned int page_count ) {
432         return arbel_cmd ( arbel,
433                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_UNMAP_ICM ),
434                            0, NULL, page_count, NULL );
435 }
436
437 static inline int
438 arbel_cmd_map_icm ( struct arbel *arbel,
439                     const struct arbelprm_virtual_physical_mapping *map ) {
440         return arbel_cmd ( arbel,
441                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_MAP_ICM,
442                                               1, sizeof ( *map ) ),
443                            0, map, 1, NULL );
444 }
445
446 static inline int
447 arbel_cmd_unmap_icm_aux ( struct arbel *arbel ) {
448         return arbel_cmd ( arbel,
449                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_UNMAP_ICM_AUX ),
450                            0, NULL, 0, NULL );
451 }
452
453 static inline int
454 arbel_cmd_map_icm_aux ( struct arbel *arbel,
455                         const struct arbelprm_virtual_physical_mapping *map ) {
456         return arbel_cmd ( arbel,
457                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_MAP_ICM_AUX,
458                                               1, sizeof ( *map ) ),
459                            0, map, 1, NULL );
460 }
461
462 static inline int
463 arbel_cmd_set_icm_size ( struct arbel *arbel,
464                          const struct arbelprm_scalar_parameter *icm_size,
465                          struct arbelprm_scalar_parameter *icm_aux_size ) {
466         return arbel_cmd ( arbel,
467                            ARBEL_HCR_INOUT_CMD ( ARBEL_HCR_SET_ICM_SIZE,
468                                                  0, sizeof ( *icm_size ),
469                                                  0, sizeof ( *icm_aux_size ) ),
470                            0, icm_size, 0, icm_aux_size );
471 }
472
473 static inline int
474 arbel_cmd_unmap_fa ( struct arbel *arbel ) {
475         return arbel_cmd ( arbel,
476                            ARBEL_HCR_VOID_CMD ( ARBEL_HCR_UNMAP_FA ),
477                            0, NULL, 0, NULL );
478 }
479
480 static inline int
481 arbel_cmd_map_fa ( struct arbel *arbel,
482                    const struct arbelprm_virtual_physical_mapping *map ) {
483         return arbel_cmd ( arbel,
484                            ARBEL_HCR_IN_CMD ( ARBEL_HCR_MAP_FA,
485                                               1, sizeof ( *map ) ),
486                            0, map, 1, NULL );
487 }
488
489 /***************************************************************************
490  *
491  * MAD operations
492  *
493  ***************************************************************************
494  */
495
496 /**
497  * Issue management datagram
498  *
499  * @v ibdev             Infiniband device
500  * @v mad               Management datagram
501  * @ret rc              Return status code
502  */
503 static int arbel_mad ( struct ib_device *ibdev, union ib_mad *mad ) {
504         struct arbel *arbel = ib_get_drvdata ( ibdev );
505         union arbelprm_mad mad_ifc;
506         int rc;
507
508         linker_assert ( sizeof ( *mad ) == sizeof ( mad_ifc.mad ),
509                         mad_size_mismatch );
510
511         /* Copy in request packet */
512         memcpy ( &mad_ifc.mad, mad, sizeof ( mad_ifc.mad ) );
513
514         /* Issue MAD */
515         if ( ( rc = arbel_cmd_mad_ifc ( arbel, ibdev->port,
516                                         &mad_ifc ) ) != 0 ) {
517                 DBGC ( arbel, "Arbel %p could not issue MAD IFC: %s\n",
518                        arbel, strerror ( rc ) );
519                 return rc;
520         }
521
522         /* Copy out reply packet */
523         memcpy ( mad, &mad_ifc.mad, sizeof ( *mad ) );
524
525         if ( mad->hdr.status != 0 ) {
526                 DBGC ( arbel, "Arbel %p MAD IFC status %04x\n",
527                        arbel, ntohs ( mad->hdr.status ) );
528                 return -EIO;
529         }
530         return 0;
531 }
532
533 /***************************************************************************
534  *
535  * Completion queue operations
536  *
537  ***************************************************************************
538  */
539
540 /**
541  * Create completion queue
542  *
543  * @v ibdev             Infiniband device
544  * @v cq                Completion queue
545  * @ret rc              Return status code
546  */
547 static int arbel_create_cq ( struct ib_device *ibdev,
548                              struct ib_completion_queue *cq ) {
549         struct arbel *arbel = ib_get_drvdata ( ibdev );
550         struct arbel_completion_queue *arbel_cq;
551         struct arbelprm_completion_queue_context cqctx;
552         struct arbelprm_cq_ci_db_record *ci_db_rec;
553         struct arbelprm_cq_arm_db_record *arm_db_rec;
554         int cqn_offset;
555         unsigned int i;
556         int rc;
557
558         /* Find a free completion queue number */
559         cqn_offset = arbel_alloc_qn_offset ( arbel->cq_inuse, ARBEL_MAX_CQS );
560         if ( cqn_offset < 0 ) {
561                 DBGC ( arbel, "Arbel %p out of completion queues\n", arbel );
562                 rc = cqn_offset;
563                 goto err_cqn_offset;
564         }
565         cq->cqn = ( arbel->limits.reserved_cqs + cqn_offset );
566
567         /* Allocate control structures */
568         arbel_cq = zalloc ( sizeof ( *arbel_cq ) );
569         if ( ! arbel_cq ) {
570                 rc = -ENOMEM;
571                 goto err_arbel_cq;
572         }
573         arbel_cq->ci_doorbell_idx = arbel_cq_ci_doorbell_idx ( cqn_offset );
574         arbel_cq->arm_doorbell_idx = arbel_cq_arm_doorbell_idx ( cqn_offset );
575
576         /* Allocate completion queue itself */
577         arbel_cq->cqe_size = ( cq->num_cqes * sizeof ( arbel_cq->cqe[0] ) );
578         arbel_cq->cqe = malloc_dma ( arbel_cq->cqe_size,
579                                      sizeof ( arbel_cq->cqe[0] ) );
580         if ( ! arbel_cq->cqe ) {
581                 rc = -ENOMEM;
582                 goto err_cqe;
583         }
584         memset ( arbel_cq->cqe, 0, arbel_cq->cqe_size );
585         for ( i = 0 ; i < cq->num_cqes ; i++ ) {
586                 MLX_FILL_1 ( &arbel_cq->cqe[i].normal, 7, owner, 1 );
587         }
588         barrier();
589
590         /* Initialise doorbell records */
591         ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
592         MLX_FILL_1 ( ci_db_rec, 0, counter, 0 );
593         MLX_FILL_2 ( ci_db_rec, 1,
594                      res, ARBEL_UAR_RES_CQ_CI,
595                      cq_number, cq->cqn );
596         arm_db_rec = &arbel->db_rec[arbel_cq->arm_doorbell_idx].cq_arm;
597         MLX_FILL_1 ( arm_db_rec, 0, counter, 0 );
598         MLX_FILL_2 ( arm_db_rec, 1,
599                      res, ARBEL_UAR_RES_CQ_ARM,
600                      cq_number, cq->cqn );
601
602         /* Hand queue over to hardware */
603         memset ( &cqctx, 0, sizeof ( cqctx ) );
604         MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ );
605         MLX_FILL_1 ( &cqctx, 2, start_address_l,
606                      virt_to_bus ( arbel_cq->cqe ) );
607         MLX_FILL_2 ( &cqctx, 3,
608                      usr_page, arbel->limits.reserved_uars,
609                      log_cq_size, fls ( cq->num_cqes - 1 ) );
610         MLX_FILL_1 ( &cqctx, 5, c_eqn, ARBEL_NO_EQ );
611         MLX_FILL_1 ( &cqctx, 6, pd, ARBEL_GLOBAL_PD );
612         MLX_FILL_1 ( &cqctx, 7, l_key, arbel->reserved_lkey );
613         MLX_FILL_1 ( &cqctx, 12, cqn, cq->cqn );
614         MLX_FILL_1 ( &cqctx, 13,
615                      cq_ci_db_record, arbel_cq->ci_doorbell_idx );
616         MLX_FILL_1 ( &cqctx, 14,
617                      cq_state_db_record, arbel_cq->arm_doorbell_idx );
618         if ( ( rc = arbel_cmd_sw2hw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
619                 DBGC ( arbel, "Arbel %p SW2HW_CQ failed: %s\n",
620                        arbel, strerror ( rc ) );
621                 goto err_sw2hw_cq;
622         }
623
624         DBGC ( arbel, "Arbel %p CQN %#lx ring at [%p,%p)\n",
625                arbel, cq->cqn, arbel_cq->cqe,
626                ( ( ( void * ) arbel_cq->cqe ) + arbel_cq->cqe_size ) );
627         ib_cq_set_drvdata ( cq, arbel_cq );
628         return 0;
629
630  err_sw2hw_cq:
631         MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
632         MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
633         free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
634  err_cqe:
635         free ( arbel_cq );
636  err_arbel_cq:
637         arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
638  err_cqn_offset:
639         return rc;
640 }
641
642 /**
643  * Destroy completion queue
644  *
645  * @v ibdev             Infiniband device
646  * @v cq                Completion queue
647  */
648 static void arbel_destroy_cq ( struct ib_device *ibdev,
649                                struct ib_completion_queue *cq ) {
650         struct arbel *arbel = ib_get_drvdata ( ibdev );
651         struct arbel_completion_queue *arbel_cq = ib_cq_get_drvdata ( cq );
652         struct arbelprm_completion_queue_context cqctx;
653         struct arbelprm_cq_ci_db_record *ci_db_rec;
654         struct arbelprm_cq_arm_db_record *arm_db_rec;
655         int cqn_offset;
656         int rc;
657
658         /* Take ownership back from hardware */
659         if ( ( rc = arbel_cmd_hw2sw_cq ( arbel, cq->cqn, &cqctx ) ) != 0 ) {
660                 DBGC ( arbel, "Arbel %p FATAL HW2SW_CQ failed on CQN %#lx: "
661                        "%s\n", arbel, cq->cqn, strerror ( rc ) );
662                 /* Leak memory and return; at least we avoid corruption */
663                 return;
664         }
665
666         /* Clear doorbell records */
667         ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
668         arm_db_rec = &arbel->db_rec[arbel_cq->arm_doorbell_idx].cq_arm;
669         MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
670         MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
671
672         /* Free memory */
673         free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
674         free ( arbel_cq );
675
676         /* Mark queue number as free */
677         cqn_offset = ( cq->cqn - arbel->limits.reserved_cqs );
678         arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
679
680         ib_cq_set_drvdata ( cq, NULL );
681 }
682
683 /***************************************************************************
684  *
685  * Queue pair operations
686  *
687  ***************************************************************************
688  */
689
690 /**
691  * Create send work queue
692  *
693  * @v arbel_send_wq     Send work queue
694  * @v num_wqes          Number of work queue entries
695  * @ret rc              Return status code
696  */
697 static int arbel_create_send_wq ( struct arbel_send_work_queue *arbel_send_wq,
698                                   unsigned int num_wqes ) {
699         struct arbelprm_ud_send_wqe *wqe;
700         struct arbelprm_ud_send_wqe *next_wqe;
701         unsigned int wqe_idx_mask;
702         unsigned int i;
703
704         /* Allocate work queue */
705         arbel_send_wq->wqe_size = ( num_wqes *
706                                     sizeof ( arbel_send_wq->wqe[0] ) );
707         arbel_send_wq->wqe = malloc_dma ( arbel_send_wq->wqe_size,
708                                           sizeof ( arbel_send_wq->wqe[0] ) );
709         if ( ! arbel_send_wq->wqe )
710                 return -ENOMEM;
711         memset ( arbel_send_wq->wqe, 0, arbel_send_wq->wqe_size );
712
713         /* Link work queue entries */
714         wqe_idx_mask = ( num_wqes - 1 );
715         for ( i = 0 ; i < num_wqes ; i++ ) {
716                 wqe = &arbel_send_wq->wqe[i].ud;
717                 next_wqe = &arbel_send_wq->wqe[ ( i + 1 ) & wqe_idx_mask ].ud;
718                 MLX_FILL_1 ( &wqe->next, 0, nda_31_6,
719                              ( virt_to_bus ( next_wqe ) >> 6 ) );
720         }
721         
722         return 0;
723 }
724
725 /**
726  * Create receive work queue
727  *
728  * @v arbel_recv_wq     Receive work queue
729  * @v num_wqes          Number of work queue entries
730  * @ret rc              Return status code
731  */
732 static int arbel_create_recv_wq ( struct arbel_recv_work_queue *arbel_recv_wq,
733                                   unsigned int num_wqes ) {
734         struct arbelprm_recv_wqe *wqe;
735         struct arbelprm_recv_wqe *next_wqe;
736         unsigned int wqe_idx_mask;
737         size_t nds;
738         unsigned int i;
739         unsigned int j;
740
741         /* Allocate work queue */
742         arbel_recv_wq->wqe_size = ( num_wqes *
743                                     sizeof ( arbel_recv_wq->wqe[0] ) );
744         arbel_recv_wq->wqe = malloc_dma ( arbel_recv_wq->wqe_size,
745                                           sizeof ( arbel_recv_wq->wqe[0] ) );
746         if ( ! arbel_recv_wq->wqe )
747                 return -ENOMEM;
748         memset ( arbel_recv_wq->wqe, 0, arbel_recv_wq->wqe_size );
749
750         /* Link work queue entries */
751         wqe_idx_mask = ( num_wqes - 1 );
752         nds = ( ( offsetof ( typeof ( *wqe ), data ) +
753                   sizeof ( wqe->data[0] ) ) >> 4 );
754         for ( i = 0 ; i < num_wqes ; i++ ) {
755                 wqe = &arbel_recv_wq->wqe[i].recv;
756                 next_wqe = &arbel_recv_wq->wqe[( i + 1 ) & wqe_idx_mask].recv;
757                 MLX_FILL_1 ( &wqe->next, 0, nda_31_6,
758                              ( virt_to_bus ( next_wqe ) >> 6 ) );
759                 MLX_FILL_1 ( &wqe->next, 1, nds, ( sizeof ( *wqe ) / 16 ) );
760                 for ( j = 0 ; ( ( ( void * ) &wqe->data[j] ) <
761                                 ( ( void * ) ( wqe + 1 ) ) ) ; j++ ) {
762                         MLX_FILL_1 ( &wqe->data[j], 1,
763                                      l_key, ARBEL_INVALID_LKEY );
764                 }
765         }
766         
767         return 0;
768 }
769
770 /**
771  * Create queue pair
772  *
773  * @v ibdev             Infiniband device
774  * @v qp                Queue pair
775  * @ret rc              Return status code
776  */
777 static int arbel_create_qp ( struct ib_device *ibdev,
778                              struct ib_queue_pair *qp ) {
779         struct arbel *arbel = ib_get_drvdata ( ibdev );
780         struct arbel_queue_pair *arbel_qp;
781         struct arbelprm_qp_ee_state_transitions qpctx;
782         struct arbelprm_qp_db_record *send_db_rec;
783         struct arbelprm_qp_db_record *recv_db_rec;
784         int qpn_offset;
785         int rc;
786
787         /* Find a free queue pair number */
788         qpn_offset = arbel_alloc_qn_offset ( arbel->qp_inuse, ARBEL_MAX_QPS );
789         if ( qpn_offset < 0 ) {
790                 DBGC ( arbel, "Arbel %p out of queue pairs\n", arbel );
791                 rc = qpn_offset;
792                 goto err_qpn_offset;
793         }
794         qp->qpn = ( ARBEL_QPN_BASE + arbel->limits.reserved_qps + qpn_offset );
795
796         /* Allocate control structures */
797         arbel_qp = zalloc ( sizeof ( *arbel_qp ) );
798         if ( ! arbel_qp ) {
799                 rc = -ENOMEM;
800                 goto err_arbel_qp;
801         }
802         arbel_qp->send.doorbell_idx = arbel_send_doorbell_idx ( qpn_offset );
803         arbel_qp->recv.doorbell_idx = arbel_recv_doorbell_idx ( qpn_offset );
804
805         /* Create send and receive work queues */
806         if ( ( rc = arbel_create_send_wq ( &arbel_qp->send,
807                                            qp->send.num_wqes ) ) != 0 )
808                 goto err_create_send_wq;
809         if ( ( rc = arbel_create_recv_wq ( &arbel_qp->recv,
810                                            qp->recv.num_wqes ) ) != 0 )
811                 goto err_create_recv_wq;
812
813         /* Initialise doorbell records */
814         send_db_rec = &arbel->db_rec[arbel_qp->send.doorbell_idx].qp;
815         MLX_FILL_1 ( send_db_rec, 0, counter, 0 );
816         MLX_FILL_2 ( send_db_rec, 1,
817                      res, ARBEL_UAR_RES_SQ,
818                      qp_number, qp->qpn );
819         recv_db_rec = &arbel->db_rec[arbel_qp->recv.doorbell_idx].qp;
820         MLX_FILL_1 ( recv_db_rec, 0, counter, 0 );
821         MLX_FILL_2 ( recv_db_rec, 1,
822                      res, ARBEL_UAR_RES_RQ,
823                      qp_number, qp->qpn );
824
825         /* Hand queue over to hardware */
826         memset ( &qpctx, 0, sizeof ( qpctx ) );
827         MLX_FILL_3 ( &qpctx, 2,
828                      qpc_eec_data.de, 1,
829                      qpc_eec_data.pm_state, 0x03 /* Always 0x03 for UD */,
830                      qpc_eec_data.st, ARBEL_ST_UD );
831         MLX_FILL_6 ( &qpctx, 4,
832                      qpc_eec_data.mtu, ARBEL_MTU_2048,
833                      qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */,
834                      qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
835                      qpc_eec_data.log_rq_stride,
836                      ( fls ( sizeof ( arbel_qp->recv.wqe[0] ) - 1 ) - 4 ),
837                      qpc_eec_data.log_sq_size, fls ( qp->send.num_wqes - 1 ),
838                      qpc_eec_data.log_sq_stride,
839                      ( fls ( sizeof ( arbel_qp->send.wqe[0] ) - 1 ) - 4 ) );
840         MLX_FILL_1 ( &qpctx, 5,
841                      qpc_eec_data.usr_page, arbel->limits.reserved_uars );
842         MLX_FILL_1 ( &qpctx, 10, qpc_eec_data.primary_address_path.port_number,
843                      ibdev->port );
844         MLX_FILL_1 ( &qpctx, 27, qpc_eec_data.pd, ARBEL_GLOBAL_PD );
845         MLX_FILL_1 ( &qpctx, 29, qpc_eec_data.wqe_lkey, arbel->reserved_lkey );
846         MLX_FILL_1 ( &qpctx, 30, qpc_eec_data.ssc, 1 );
847         MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn );
848         MLX_FILL_1 ( &qpctx, 34, qpc_eec_data.snd_wqe_base_adr_l,
849                      ( virt_to_bus ( arbel_qp->send.wqe ) >> 6 ) );
850         MLX_FILL_1 ( &qpctx, 35, qpc_eec_data.snd_db_record_index,
851                      arbel_qp->send.doorbell_idx );
852         MLX_FILL_1 ( &qpctx, 38, qpc_eec_data.rsc, 1 );
853         MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn );
854         MLX_FILL_1 ( &qpctx, 42, qpc_eec_data.rcv_wqe_base_adr_l,
855                      ( virt_to_bus ( arbel_qp->recv.wqe ) >> 6 ) );
856         MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.rcv_db_record_index,
857                      arbel_qp->recv.doorbell_idx );
858         if ( ( rc = arbel_cmd_rst2init_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
859                 DBGC ( arbel, "Arbel %p RST2INIT_QPEE failed: %s\n",
860                        arbel, strerror ( rc ) );
861                 goto err_rst2init_qpee;
862         }
863         memset ( &qpctx, 0, sizeof ( qpctx ) );
864         MLX_FILL_2 ( &qpctx, 4,
865                      qpc_eec_data.mtu, ARBEL_MTU_2048,
866                      qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */ );
867         if ( ( rc = arbel_cmd_init2rtr_qpee ( arbel, qp->qpn, &qpctx )) != 0 ){
868                 DBGC ( arbel, "Arbel %p INIT2RTR_QPEE failed: %s\n",
869                        arbel, strerror ( rc ) );
870                 goto err_init2rtr_qpee;
871         }
872         memset ( &qpctx, 0, sizeof ( qpctx ) );
873         if ( ( rc = arbel_cmd_rtr2rts_qpee ( arbel, qp->qpn, &qpctx ) ) != 0 ){
874                 DBGC ( arbel, "Arbel %p RTR2RTS_QPEE failed: %s\n",
875                        arbel, strerror ( rc ) );
876                 goto err_rtr2rts_qpee;
877         }
878
879         DBGC ( arbel, "Arbel %p QPN %#lx send ring at [%p,%p)\n",
880                arbel, qp->qpn, arbel_qp->send.wqe,
881                ( ( (void *) arbel_qp->send.wqe ) + arbel_qp->send.wqe_size ) );
882         DBGC ( arbel, "Arbel %p QPN %#lx receive ring at [%p,%p)\n",
883                arbel, qp->qpn, arbel_qp->recv.wqe,
884                ( ( (void *) arbel_qp->recv.wqe ) + arbel_qp->recv.wqe_size ) );
885         ib_qp_set_drvdata ( qp, arbel_qp );
886         return 0;
887
888  err_rtr2rts_qpee:
889  err_init2rtr_qpee:
890         arbel_cmd_2rst_qpee ( arbel, qp->qpn );
891  err_rst2init_qpee:
892         MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
893         MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
894         free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
895  err_create_recv_wq:
896         free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
897  err_create_send_wq:
898         free ( arbel_qp );
899  err_arbel_qp:
900         arbel_free_qn_offset ( arbel->qp_inuse, qpn_offset );
901  err_qpn_offset:
902         return rc;
903 }
904
905 /**
906  * Modify queue pair
907  *
908  * @v ibdev             Infiniband device
909  * @v qp                Queue pair
910  * @ret rc              Return status code
911  */
912 static int arbel_modify_qp ( struct ib_device *ibdev,
913                              struct ib_queue_pair *qp ) {
914         struct arbel *arbel = ib_get_drvdata ( ibdev );
915         struct arbelprm_qp_ee_state_transitions qpctx;
916         int rc;
917
918         /* Issue RTS2RTS_QP */
919         memset ( &qpctx, 0, sizeof ( qpctx ) );
920         MLX_FILL_1 ( &qpctx, 0, opt_param_mask, ARBEL_QPEE_OPT_PARAM_QKEY );
921         MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey );
922         if ( ( rc = arbel_cmd_rts2rts_qp ( arbel, qp->qpn, &qpctx ) ) != 0 ){
923                 DBGC ( arbel, "Arbel %p RTS2RTS_QP failed: %s\n",
924                        arbel, strerror ( rc ) );
925                 return rc;
926         }
927
928         return 0;
929 }
930
931 /**
932  * Destroy queue pair
933  *
934  * @v ibdev             Infiniband device
935  * @v qp                Queue pair
936  */
937 static void arbel_destroy_qp ( struct ib_device *ibdev,
938                                struct ib_queue_pair *qp ) {
939         struct arbel *arbel = ib_get_drvdata ( ibdev );
940         struct arbel_queue_pair *arbel_qp = ib_qp_get_drvdata ( qp );
941         struct arbelprm_qp_db_record *send_db_rec;
942         struct arbelprm_qp_db_record *recv_db_rec;
943         int qpn_offset;
944         int rc;
945
946         /* Take ownership back from hardware */
947         if ( ( rc = arbel_cmd_2rst_qpee ( arbel, qp->qpn ) ) != 0 ) {
948                 DBGC ( arbel, "Arbel %p FATAL 2RST_QPEE failed on QPN %#lx: "
949                        "%s\n", arbel, qp->qpn, strerror ( rc ) );
950                 /* Leak memory and return; at least we avoid corruption */
951                 return;
952         }
953
954         /* Clear doorbell records */
955         send_db_rec = &arbel->db_rec[arbel_qp->send.doorbell_idx].qp;
956         recv_db_rec = &arbel->db_rec[arbel_qp->recv.doorbell_idx].qp;
957         MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
958         MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
959
960         /* Free memory */
961         free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
962         free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
963         free ( arbel_qp );
964
965         /* Mark queue number as free */
966         qpn_offset = ( qp->qpn - ARBEL_QPN_BASE - arbel->limits.reserved_qps );
967         arbel_free_qn_offset ( arbel->qp_inuse, qpn_offset );
968
969         ib_qp_set_drvdata ( qp, NULL );
970 }
971
972 /***************************************************************************
973  *
974  * Work request operations
975  *
976  ***************************************************************************
977  */
978
979 /**
980  * Ring doorbell register in UAR
981  *
982  * @v arbel             Arbel device
983  * @v db_reg            Doorbell register structure
984  * @v offset            Address of doorbell
985  */
986 static void arbel_ring_doorbell ( struct arbel *arbel,
987                                   union arbelprm_doorbell_register *db_reg,
988                                   unsigned int offset ) {
989
990         DBGC2 ( arbel, "Arbel %p ringing doorbell %08x:%08x at %lx\n",
991                 arbel, db_reg->dword[0], db_reg->dword[1],
992                 virt_to_phys ( arbel->uar + offset ) );
993
994         barrier();
995         writel ( db_reg->dword[0], ( arbel->uar + offset + 0 ) );
996         barrier();
997         writel ( db_reg->dword[1], ( arbel->uar + offset + 4 ) );
998 }
999
1000 /** GID used for GID-less send work queue entries */
1001 static const struct ib_gid arbel_no_gid = {
1002         { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 } }
1003 };
1004
1005 /**
1006  * Post send work queue entry
1007  *
1008  * @v ibdev             Infiniband device
1009  * @v qp                Queue pair
1010  * @v av                Address vector
1011  * @v iobuf             I/O buffer
1012  * @ret rc              Return status code
1013  */
1014 static int arbel_post_send ( struct ib_device *ibdev,
1015                              struct ib_queue_pair *qp,
1016                              struct ib_address_vector *av,
1017                              struct io_buffer *iobuf ) {
1018         struct arbel *arbel = ib_get_drvdata ( ibdev );
1019         struct arbel_queue_pair *arbel_qp = ib_qp_get_drvdata ( qp );
1020         struct ib_work_queue *wq = &qp->send;
1021         struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
1022         struct arbelprm_ud_send_wqe *prev_wqe;
1023         struct arbelprm_ud_send_wqe *wqe;
1024         struct arbelprm_qp_db_record *qp_db_rec;
1025         union arbelprm_doorbell_register db_reg;
1026         const struct ib_gid *gid;
1027         unsigned int wqe_idx_mask;
1028         size_t nds;
1029
1030         /* Allocate work queue entry */
1031         wqe_idx_mask = ( wq->num_wqes - 1 );
1032         if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
1033                 DBGC ( arbel, "Arbel %p send queue full", arbel );
1034                 return -ENOBUFS;
1035         }
1036         wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
1037         prev_wqe = &arbel_send_wq->wqe[(wq->next_idx - 1) & wqe_idx_mask].ud;
1038         wqe = &arbel_send_wq->wqe[wq->next_idx & wqe_idx_mask].ud;
1039
1040         /* Construct work queue entry */
1041         MLX_FILL_1 ( &wqe->next, 1, always1, 1 );
1042         memset ( &wqe->ctrl, 0, sizeof ( wqe->ctrl ) );
1043         MLX_FILL_1 ( &wqe->ctrl, 0, always1, 1 );
1044         memset ( &wqe->ud, 0, sizeof ( wqe->ud ) );
1045         MLX_FILL_2 ( &wqe->ud, 0,
1046                      ud_address_vector.pd, ARBEL_GLOBAL_PD,
1047                      ud_address_vector.port_number, ibdev->port );
1048         MLX_FILL_2 ( &wqe->ud, 1,
1049                      ud_address_vector.rlid, av->lid,
1050                      ud_address_vector.g, av->gid_present );
1051         MLX_FILL_2 ( &wqe->ud, 2,
1052                      ud_address_vector.max_stat_rate,
1053                          ( ( av->rate >= 3 ) ? 0 : 1 ),
1054                      ud_address_vector.msg, 3 );
1055         MLX_FILL_1 ( &wqe->ud, 3, ud_address_vector.sl, av->sl );
1056         gid = ( av->gid_present ? &av->gid : &arbel_no_gid );
1057         memcpy ( &wqe->ud.u.dwords[4], gid, sizeof ( *gid ) );
1058         MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->qpn );
1059         MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
1060         MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
1061         MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
1062         MLX_FILL_1 ( &wqe->data[0], 3,
1063                      local_address_l, virt_to_bus ( iobuf->data ) );
1064
1065         /* Update previous work queue entry's "next" field */
1066         nds = ( ( offsetof ( typeof ( *wqe ), data ) +
1067                   sizeof ( wqe->data[0] ) ) >> 4 );
1068         MLX_SET ( &prev_wqe->next, nopcode, ARBEL_OPCODE_SEND );
1069         MLX_FILL_3 ( &prev_wqe->next, 1,
1070                      nds, nds,
1071                      f, 1,
1072                      always1, 1 );
1073
1074         /* Update doorbell record */
1075         barrier();
1076         qp_db_rec = &arbel->db_rec[arbel_send_wq->doorbell_idx].qp;
1077         MLX_FILL_1 ( qp_db_rec, 0,
1078                      counter, ( ( wq->next_idx + 1 ) & 0xffff ) );
1079
1080         /* Ring doorbell register */
1081         MLX_FILL_4 ( &db_reg.send, 0,
1082                      nopcode, ARBEL_OPCODE_SEND,
1083                      f, 1,
1084                      wqe_counter, ( wq->next_idx & 0xffff ),
1085                      wqe_cnt, 1 );
1086         MLX_FILL_2 ( &db_reg.send, 1,
1087                      nds, nds,
1088                      qpn, qp->qpn );
1089         arbel_ring_doorbell ( arbel, &db_reg, ARBEL_DB_POST_SND_OFFSET );
1090
1091         /* Update work queue's index */
1092         wq->next_idx++;
1093
1094         return 0;
1095 }
1096
1097 /**
1098  * Post receive work queue entry
1099  *
1100  * @v ibdev             Infiniband device
1101  * @v qp                Queue pair
1102  * @v iobuf             I/O buffer
1103  * @ret rc              Return status code
1104  */
1105 static int arbel_post_recv ( struct ib_device *ibdev,
1106                              struct ib_queue_pair *qp,
1107                              struct io_buffer *iobuf ) {
1108         struct arbel *arbel = ib_get_drvdata ( ibdev );
1109         struct arbel_queue_pair *arbel_qp = ib_qp_get_drvdata ( qp );
1110         struct ib_work_queue *wq = &qp->recv;
1111         struct arbel_recv_work_queue *arbel_recv_wq = &arbel_qp->recv;
1112         struct arbelprm_recv_wqe *wqe;
1113         union arbelprm_doorbell_record *db_rec;
1114         unsigned int wqe_idx_mask;
1115
1116         /* Allocate work queue entry */
1117         wqe_idx_mask = ( wq->num_wqes - 1 );
1118         if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) {
1119                 DBGC ( arbel, "Arbel %p receive queue full", arbel );
1120                 return -ENOBUFS;
1121         }
1122         wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf;
1123         wqe = &arbel_recv_wq->wqe[wq->next_idx & wqe_idx_mask].recv;
1124
1125         /* Construct work queue entry */
1126         MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) );
1127         MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
1128         MLX_FILL_1 ( &wqe->data[0], 3,
1129                      local_address_l, virt_to_bus ( iobuf->data ) );
1130
1131         /* Update doorbell record */
1132         barrier();
1133         db_rec = &arbel->db_rec[arbel_recv_wq->doorbell_idx];
1134         MLX_FILL_1 ( &db_rec->qp, 0,
1135                      counter, ( ( wq->next_idx + 1 ) & 0xffff ) );      
1136
1137         /* Update work queue's index */
1138         wq->next_idx++;
1139
1140         return 0;       
1141 }
1142
1143 /**
1144  * Handle completion
1145  *
1146  * @v ibdev             Infiniband device
1147  * @v cq                Completion queue
1148  * @v cqe               Hardware completion queue entry
1149  * @ret rc              Return status code
1150  */
1151 static int arbel_complete ( struct ib_device *ibdev,
1152                             struct ib_completion_queue *cq,
1153                             union arbelprm_completion_entry *cqe ) {
1154         struct arbel *arbel = ib_get_drvdata ( ibdev );
1155         struct ib_work_queue *wq;
1156         struct ib_queue_pair *qp;
1157         struct arbel_queue_pair *arbel_qp;
1158         struct arbel_send_work_queue *arbel_send_wq;
1159         struct arbel_recv_work_queue *arbel_recv_wq;
1160         struct arbelprm_recv_wqe *recv_wqe;
1161         struct io_buffer *iobuf;
1162         struct ib_address_vector av;
1163         struct ib_global_route_header *grh;
1164         unsigned int opcode;
1165         unsigned long qpn;
1166         int is_send;
1167         unsigned long wqe_adr;
1168         unsigned int wqe_idx;
1169         size_t len;
1170         int rc = 0;
1171
1172         /* Parse completion */
1173         qpn = MLX_GET ( &cqe->normal, my_qpn );
1174         is_send = MLX_GET ( &cqe->normal, s );
1175         wqe_adr = ( MLX_GET ( &cqe->normal, wqe_adr ) << 6 );
1176         opcode = MLX_GET ( &cqe->normal, opcode );
1177         if ( opcode >= ARBEL_OPCODE_RECV_ERROR ) {
1178                 /* "s" field is not valid for error opcodes */
1179                 is_send = ( opcode == ARBEL_OPCODE_SEND_ERROR );
1180                 DBGC ( arbel, "Arbel %p CPN %lx syndrome %x vendor %x\n",
1181                        arbel, cq->cqn, MLX_GET ( &cqe->error, syndrome ),
1182                        MLX_GET ( &cqe->error, vendor_code ) );
1183                 rc = -EIO;
1184                 /* Don't return immediately; propagate error to completer */
1185         }
1186
1187         /* Identify work queue */
1188         wq = ib_find_wq ( cq, qpn, is_send );
1189         if ( ! wq ) {
1190                 DBGC ( arbel, "Arbel %p CQN %lx unknown %s QPN %lx\n",
1191                        arbel, cq->cqn, ( is_send ? "send" : "recv" ), qpn );
1192                 return -EIO;
1193         }
1194         qp = wq->qp;
1195         arbel_qp = ib_qp_get_drvdata ( qp );
1196         arbel_send_wq = &arbel_qp->send;
1197         arbel_recv_wq = &arbel_qp->recv;
1198
1199         /* Identify work queue entry index */
1200         if ( is_send ) {
1201                 wqe_idx = ( ( wqe_adr - virt_to_bus ( arbel_send_wq->wqe ) ) /
1202                             sizeof ( arbel_send_wq->wqe[0] ) );
1203                 assert ( wqe_idx < qp->send.num_wqes );
1204         } else {
1205                 wqe_idx = ( ( wqe_adr - virt_to_bus ( arbel_recv_wq->wqe ) ) /
1206                             sizeof ( arbel_recv_wq->wqe[0] ) );
1207                 assert ( wqe_idx < qp->recv.num_wqes );
1208         }
1209
1210         /* Identify I/O buffer */
1211         iobuf = wq->iobufs[wqe_idx];
1212         if ( ! iobuf ) {
1213                 DBGC ( arbel, "Arbel %p CQN %lx QPN %lx empty WQE %x\n",
1214                        arbel, cq->cqn, qpn, wqe_idx );
1215                 return -EIO;
1216         }
1217         wq->iobufs[wqe_idx] = NULL;
1218
1219         if ( is_send ) {
1220                 /* Hand off to completion handler */
1221                 ib_complete_send ( ibdev, qp, iobuf, rc );
1222         } else {
1223                 /* Set received length */
1224                 len = MLX_GET ( &cqe->normal, byte_cnt );
1225                 recv_wqe = &arbel_recv_wq->wqe[wqe_idx].recv;
1226                 assert ( MLX_GET ( &recv_wqe->data[0], local_address_l ) ==
1227                          virt_to_bus ( iobuf->data ) );
1228                 assert ( MLX_GET ( &recv_wqe->data[0], byte_count ) ==
1229                          iob_tailroom ( iobuf ) );
1230                 MLX_FILL_1 ( &recv_wqe->data[0], 0, byte_count, 0 );
1231                 MLX_FILL_1 ( &recv_wqe->data[0], 1,
1232                              l_key, ARBEL_INVALID_LKEY );
1233                 assert ( len <= iob_tailroom ( iobuf ) );
1234                 iob_put ( iobuf, len );
1235                 assert ( iob_len ( iobuf ) >= sizeof ( *grh ) );
1236                 grh = iobuf->data;
1237                 iob_pull ( iobuf, sizeof ( *grh ) );
1238                 /* Construct address vector */
1239                 memset ( &av, 0, sizeof ( av ) );
1240                 av.qpn = MLX_GET ( &cqe->normal, rqpn );
1241                 av.lid = MLX_GET ( &cqe->normal, rlid );
1242                 av.sl = MLX_GET ( &cqe->normal, sl );
1243                 av.gid_present = MLX_GET ( &cqe->normal, g );
1244                 memcpy ( &av.gid, &grh->sgid, sizeof ( av.gid ) );
1245                 /* Hand off to completion handler */
1246                 ib_complete_recv ( ibdev, qp, &av, iobuf, rc );
1247         }
1248
1249         return rc;
1250 }                            
1251
1252 /**
1253  * Poll completion queue
1254  *
1255  * @v ibdev             Infiniband device
1256  * @v cq                Completion queue
1257  */
1258 static void arbel_poll_cq ( struct ib_device *ibdev,
1259                             struct ib_completion_queue *cq ) {
1260         struct arbel *arbel = ib_get_drvdata ( ibdev );
1261         struct arbel_completion_queue *arbel_cq = ib_cq_get_drvdata ( cq );
1262         struct arbelprm_cq_ci_db_record *ci_db_rec;
1263         union arbelprm_completion_entry *cqe;
1264         unsigned int cqe_idx_mask;
1265         int rc;
1266
1267         while ( 1 ) {
1268                 /* Look for completion entry */
1269                 cqe_idx_mask = ( cq->num_cqes - 1 );
1270                 cqe = &arbel_cq->cqe[cq->next_idx & cqe_idx_mask];
1271                 if ( MLX_GET ( &cqe->normal, owner ) != 0 ) {
1272                         /* Entry still owned by hardware; end of poll */
1273                         break;
1274                 }
1275
1276                 /* Handle completion */
1277                 if ( ( rc = arbel_complete ( ibdev, cq, cqe ) ) != 0 ) {
1278                         DBGC ( arbel, "Arbel %p failed to complete: %s\n",
1279                                arbel, strerror ( rc ) );
1280                         DBGC_HD ( arbel, cqe, sizeof ( *cqe ) );
1281                 }
1282
1283                 /* Return ownership to hardware */
1284                 MLX_FILL_1 ( &cqe->normal, 7, owner, 1 );
1285                 barrier();
1286                 /* Update completion queue's index */
1287                 cq->next_idx++;
1288                 /* Update doorbell record */
1289                 ci_db_rec = &arbel->db_rec[arbel_cq->ci_doorbell_idx].cq_ci;
1290                 MLX_FILL_1 ( ci_db_rec, 0,
1291                              counter, ( cq->next_idx & 0xffffffffUL ) );
1292         }
1293 }
1294
1295 /***************************************************************************
1296  *
1297  * Event queues
1298  *
1299  ***************************************************************************
1300  */
1301
1302 /**
1303  * Create event queue
1304  *
1305  * @v arbel             Arbel device
1306  * @ret rc              Return status code
1307  */
1308 static int arbel_create_eq ( struct arbel *arbel ) {
1309         struct arbel_event_queue *arbel_eq = &arbel->eq;
1310         struct arbelprm_eqc eqctx;
1311         struct arbelprm_event_mask mask;
1312         unsigned int i;
1313         int rc;
1314
1315         /* Select event queue number */
1316         arbel_eq->eqn = arbel->limits.reserved_eqs;
1317
1318         /* Calculate doorbell address */
1319         arbel_eq->doorbell = ( arbel->eq_ci_doorbells +
1320                                ARBEL_DB_EQ_OFFSET ( arbel_eq->eqn ) );
1321
1322         /* Allocate event queue itself */
1323         arbel_eq->eqe_size =
1324                 ( ARBEL_NUM_EQES * sizeof ( arbel_eq->eqe[0] ) );
1325         arbel_eq->eqe = malloc_dma ( arbel_eq->eqe_size,
1326                                      sizeof ( arbel_eq->eqe[0] ) );
1327         if ( ! arbel_eq->eqe ) {
1328                 rc = -ENOMEM;
1329                 goto err_eqe;
1330         }
1331         memset ( arbel_eq->eqe, 0, arbel_eq->eqe_size );
1332         for ( i = 0 ; i < ARBEL_NUM_EQES ; i++ ) {
1333                 MLX_FILL_1 ( &arbel_eq->eqe[i].generic, 7, owner, 1 );
1334         }
1335         barrier();
1336
1337         /* Hand queue over to hardware */
1338         memset ( &eqctx, 0, sizeof ( eqctx ) );
1339         MLX_FILL_1 ( &eqctx, 0, st, 0xa /* "Fired" */ );
1340         MLX_FILL_1 ( &eqctx, 2,
1341                      start_address_l, virt_to_phys ( arbel_eq->eqe ) );
1342         MLX_FILL_1 ( &eqctx, 3, log_eq_size, fls ( ARBEL_NUM_EQES - 1 ) );
1343         MLX_FILL_1 ( &eqctx, 6, pd, ARBEL_GLOBAL_PD );
1344         MLX_FILL_1 ( &eqctx, 7, lkey, arbel->reserved_lkey );
1345         if ( ( rc = arbel_cmd_sw2hw_eq ( arbel, arbel_eq->eqn,
1346                                          &eqctx ) ) != 0 ) {
1347                 DBGC ( arbel, "Arbel %p SW2HW_EQ failed: %s\n",
1348                        arbel, strerror ( rc ) );
1349                 goto err_sw2hw_eq;
1350         }
1351
1352         /* Map events to this event queue */
1353         memset ( &mask, 0, sizeof ( mask ) );
1354         MLX_FILL_1 ( &mask, 1, port_state_change, 1 );
1355         if ( ( rc = arbel_cmd_map_eq ( arbel,
1356                                        ( ARBEL_MAP_EQ | arbel_eq->eqn ),
1357                                        &mask ) ) != 0 ) {
1358                 DBGC ( arbel, "Arbel %p MAP_EQ failed: %s\n",
1359                        arbel, strerror ( rc )  );
1360                 goto err_map_eq;
1361         }
1362
1363         DBGC ( arbel, "Arbel %p EQN %#lx ring at [%p,%p])\n",
1364                arbel, arbel_eq->eqn, arbel_eq->eqe,
1365                ( ( ( void * ) arbel_eq->eqe ) + arbel_eq->eqe_size ) );
1366         return 0;
1367
1368  err_map_eq:
1369         arbel_cmd_hw2sw_eq ( arbel, arbel_eq->eqn, &eqctx );
1370  err_sw2hw_eq:
1371         free_dma ( arbel_eq->eqe, arbel_eq->eqe_size );
1372  err_eqe:
1373         memset ( arbel_eq, 0, sizeof ( *arbel_eq ) );
1374         return rc;
1375 }
1376
1377 /**
1378  * Destroy event queue
1379  *
1380  * @v arbel             Arbel device
1381  */
1382 static void arbel_destroy_eq ( struct arbel *arbel ) {
1383         struct arbel_event_queue *arbel_eq = &arbel->eq;
1384         struct arbelprm_eqc eqctx;
1385         struct arbelprm_event_mask mask;
1386         int rc;
1387
1388         /* Unmap events from event queue */
1389         memset ( &mask, 0, sizeof ( mask ) );
1390         MLX_FILL_1 ( &mask, 1, port_state_change, 1 );
1391         if ( ( rc = arbel_cmd_map_eq ( arbel,
1392                                        ( ARBEL_UNMAP_EQ | arbel_eq->eqn ),
1393                                        &mask ) ) != 0 ) {
1394                 DBGC ( arbel, "Arbel %p FATAL MAP_EQ failed to unmap: %s\n",
1395                        arbel, strerror ( rc ) );
1396                 /* Continue; HCA may die but system should survive */
1397         }
1398
1399         /* Take ownership back from hardware */
1400         if ( ( rc = arbel_cmd_hw2sw_eq ( arbel, arbel_eq->eqn,
1401                                          &eqctx ) ) != 0 ) {
1402                 DBGC ( arbel, "Arbel %p FATAL HW2SW_EQ failed: %s\n",
1403                        arbel, strerror ( rc ) );
1404                 /* Leak memory and return; at least we avoid corruption */
1405                 return;
1406         }
1407
1408         /* Free memory */
1409         free_dma ( arbel_eq->eqe, arbel_eq->eqe_size );
1410         memset ( arbel_eq, 0, sizeof ( *arbel_eq ) );
1411 }
1412
1413 /**
1414  * Handle port state event
1415  *
1416  * @v arbel             Arbel device
1417  * @v eqe               Port state change event queue entry
1418  */
1419 static void arbel_event_port_state_change ( struct arbel *arbel,
1420                                             union arbelprm_event_entry *eqe){
1421         unsigned int port;
1422         int link_up;
1423
1424         /* Get port and link status */
1425         port = ( MLX_GET ( &eqe->port_state_change, data.p ) - 1 );
1426         link_up = ( MLX_GET ( &eqe->generic, event_sub_type ) & 0x04 );
1427         DBGC ( arbel, "Arbel %p port %d link %s\n", arbel, ( port + 1 ),
1428                ( link_up ? "up" : "down" ) );
1429
1430         /* Sanity check */
1431         if ( port >= ARBEL_NUM_PORTS ) {
1432                 DBGC ( arbel, "Arbel %p port %d does not exist!\n",
1433                        arbel, ( port + 1 ) );
1434                 return;
1435         }
1436
1437         /* Update MAD parameters */
1438         ib_smc_update ( arbel->ibdev[port], arbel_mad );
1439
1440         /* Notify Infiniband core of link state change */
1441         ib_link_state_changed ( arbel->ibdev[port] );
1442 }
1443
1444 /**
1445  * Poll event queue
1446  *
1447  * @v ibdev             Infiniband device
1448  */
1449 static void arbel_poll_eq ( struct ib_device *ibdev ) {
1450         struct arbel *arbel = ib_get_drvdata ( ibdev );
1451         struct arbel_event_queue *arbel_eq = &arbel->eq;
1452         union arbelprm_event_entry *eqe;
1453         union arbelprm_eq_doorbell_register db_reg;
1454         unsigned int eqe_idx_mask;
1455         unsigned int event_type;
1456
1457         while ( 1 ) {
1458                 /* Look for event entry */
1459                 eqe_idx_mask = ( ARBEL_NUM_EQES - 1 );
1460                 eqe = &arbel_eq->eqe[arbel_eq->next_idx & eqe_idx_mask];
1461                 if ( MLX_GET ( &eqe->generic, owner ) != 0 ) {
1462                         /* Entry still owned by hardware; end of poll */
1463                         break;
1464                 }
1465                 DBGCP ( arbel, "Arbel %p event:\n", arbel );
1466                 DBGCP_HD ( arbel, eqe, sizeof ( *eqe ) );
1467
1468                 /* Handle event */
1469                 event_type = MLX_GET ( &eqe->generic, event_type );
1470                 switch ( event_type ) {
1471                 case ARBEL_EV_PORT_STATE_CHANGE:
1472                         arbel_event_port_state_change ( arbel, eqe );
1473                         break;
1474                 default:
1475                         DBGC ( arbel, "Arbel %p unrecognised event type "
1476                                "%#x:\n", arbel, event_type );
1477                         DBGC_HD ( arbel, eqe, sizeof ( *eqe ) );
1478                         break;
1479                 }
1480
1481                 /* Return ownership to hardware */
1482                 MLX_FILL_1 ( &eqe->generic, 7, owner, 1 );
1483                 barrier();
1484
1485                 /* Update event queue's index */
1486                 arbel_eq->next_idx++;
1487
1488                 /* Ring doorbell */
1489                 MLX_FILL_1 ( &db_reg.ci, 0, ci, arbel_eq->next_idx );
1490                 DBGCP ( arbel, "Ringing doorbell %08lx with %08x\n",
1491                         virt_to_phys ( arbel_eq->doorbell ),
1492                         db_reg.dword[0] );
1493                 writel ( db_reg.dword[0], arbel_eq->doorbell );
1494         }
1495 }
1496
1497 /***************************************************************************
1498  *
1499  * Infiniband link-layer operations
1500  *
1501  ***************************************************************************
1502  */
1503
1504 /**
1505  * Initialise Infiniband link
1506  *
1507  * @v ibdev             Infiniband device
1508  * @ret rc              Return status code
1509  */
1510 static int arbel_open ( struct ib_device *ibdev ) {
1511         struct arbel *arbel = ib_get_drvdata ( ibdev );
1512         struct arbelprm_init_ib init_ib;
1513         int rc;
1514
1515         memset ( &init_ib, 0, sizeof ( init_ib ) );
1516         MLX_FILL_3 ( &init_ib, 0,
1517                      mtu_cap, ARBEL_MTU_2048,
1518                      port_width_cap, 3,
1519                      vl_cap, 1 );
1520         MLX_FILL_1 ( &init_ib, 1, max_gid, 1 );
1521         MLX_FILL_1 ( &init_ib, 2, max_pkey, 64 );
1522         if ( ( rc = arbel_cmd_init_ib ( arbel, ibdev->port,
1523                                         &init_ib ) ) != 0 ) {
1524                 DBGC ( arbel, "Arbel %p could not intialise IB: %s\n",
1525                        arbel, strerror ( rc ) );
1526                 return rc;
1527         }
1528
1529         /* Update MAD parameters */
1530         ib_smc_update ( ibdev, arbel_mad );
1531
1532         return 0;
1533 }
1534
1535 /**
1536  * Close Infiniband link
1537  *
1538  * @v ibdev             Infiniband device
1539  */
1540 static void arbel_close ( struct ib_device *ibdev ) {
1541         struct arbel *arbel = ib_get_drvdata ( ibdev );
1542         int rc;
1543
1544         if ( ( rc = arbel_cmd_close_ib ( arbel, ibdev->port ) ) != 0 ) {
1545                 DBGC ( arbel, "Arbel %p could not close IB: %s\n",
1546                        arbel, strerror ( rc ) );
1547                 /* Nothing we can do about this */
1548         }
1549 }
1550
1551 /***************************************************************************
1552  *
1553  * Multicast group operations
1554  *
1555  ***************************************************************************
1556  */
1557
1558 /**
1559  * Attach to multicast group
1560  *
1561  * @v ibdev             Infiniband device
1562  * @v qp                Queue pair
1563  * @v gid               Multicast GID
1564  * @ret rc              Return status code
1565  */
1566 static int arbel_mcast_attach ( struct ib_device *ibdev,
1567                                 struct ib_queue_pair *qp,
1568                                 struct ib_gid *gid ) {
1569         struct arbel *arbel = ib_get_drvdata ( ibdev );
1570         struct arbelprm_mgm_hash hash;
1571         struct arbelprm_mgm_entry mgm;
1572         unsigned int index;
1573         int rc;
1574
1575         /* Generate hash table index */
1576         if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
1577                 DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
1578                        arbel, strerror ( rc ) );
1579                 return rc;
1580         }
1581         index = MLX_GET ( &hash, hash );
1582
1583         /* Check for existing hash table entry */
1584         if ( ( rc = arbel_cmd_read_mgm ( arbel, index, &mgm ) ) != 0 ) {
1585                 DBGC ( arbel, "Arbel %p could not read MGM %#x: %s\n",
1586                        arbel, index, strerror ( rc ) );
1587                 return rc;
1588         }
1589         if ( MLX_GET ( &mgm, mgmqp_0.qi ) != 0 ) {
1590                 /* FIXME: this implementation allows only a single QP
1591                  * per multicast group, and doesn't handle hash
1592                  * collisions.  Sufficient for IPoIB but may need to
1593                  * be extended in future.
1594                  */
1595                 DBGC ( arbel, "Arbel %p MGID index %#x already in use\n",
1596                        arbel, index );
1597                 return -EBUSY;
1598         }
1599
1600         /* Update hash table entry */
1601         MLX_FILL_2 ( &mgm, 8,
1602                      mgmqp_0.qpn_i, qp->qpn,
1603                      mgmqp_0.qi, 1 );
1604         memcpy ( &mgm.u.dwords[4], gid, sizeof ( *gid ) );
1605         if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
1606                 DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
1607                        arbel, index, strerror ( rc ) );
1608                 return rc;
1609         }
1610
1611         return 0;
1612 }
1613
1614 /**
1615  * Detach from multicast group
1616  *
1617  * @v ibdev             Infiniband device
1618  * @v qp                Queue pair
1619  * @v gid               Multicast GID
1620  */
1621 static void arbel_mcast_detach ( struct ib_device *ibdev,
1622                                  struct ib_queue_pair *qp __unused,
1623                                  struct ib_gid *gid ) {
1624         struct arbel *arbel = ib_get_drvdata ( ibdev );
1625         struct arbelprm_mgm_hash hash;
1626         struct arbelprm_mgm_entry mgm;
1627         unsigned int index;
1628         int rc;
1629
1630         /* Generate hash table index */
1631         if ( ( rc = arbel_cmd_mgid_hash ( arbel, gid, &hash ) ) != 0 ) {
1632                 DBGC ( arbel, "Arbel %p could not hash GID: %s\n",
1633                        arbel, strerror ( rc ) );
1634                 return;
1635         }
1636         index = MLX_GET ( &hash, hash );
1637
1638         /* Clear hash table entry */
1639         memset ( &mgm, 0, sizeof ( mgm ) );
1640         if ( ( rc = arbel_cmd_write_mgm ( arbel, index, &mgm ) ) != 0 ) {
1641                 DBGC ( arbel, "Arbel %p could not write MGM %#x: %s\n",
1642                        arbel, index, strerror ( rc ) );
1643                 return;
1644         }
1645 }
1646
1647 /** Arbel Infiniband operations */
1648 static struct ib_device_operations arbel_ib_operations = {
1649         .create_cq      = arbel_create_cq,
1650         .destroy_cq     = arbel_destroy_cq,
1651         .create_qp      = arbel_create_qp,
1652         .modify_qp      = arbel_modify_qp,
1653         .destroy_qp     = arbel_destroy_qp,
1654         .post_send      = arbel_post_send,
1655         .post_recv      = arbel_post_recv,
1656         .poll_cq        = arbel_poll_cq,
1657         .poll_eq        = arbel_poll_eq,
1658         .open           = arbel_open,
1659         .close          = arbel_close,
1660         .mcast_attach   = arbel_mcast_attach,
1661         .mcast_detach   = arbel_mcast_detach,
1662 };
1663
1664 /***************************************************************************
1665  *
1666  * Firmware control
1667  *
1668  ***************************************************************************
1669  */
1670
1671 /**
1672  * Start firmware running
1673  *
1674  * @v arbel             Arbel device
1675  * @ret rc              Return status code
1676  */
1677 static int arbel_start_firmware ( struct arbel *arbel ) {
1678         struct arbelprm_query_fw fw;
1679         struct arbelprm_access_lam lam;
1680         struct arbelprm_virtual_physical_mapping map_fa;
1681         unsigned int fw_pages;
1682         unsigned int log2_fw_pages;
1683         size_t fw_size;
1684         physaddr_t fw_base;
1685         uint64_t eq_set_ci_base_addr;
1686         int rc;
1687
1688         /* Get firmware parameters */
1689         if ( ( rc = arbel_cmd_query_fw ( arbel, &fw ) ) != 0 ) {
1690                 DBGC ( arbel, "Arbel %p could not query firmware: %s\n",
1691                        arbel, strerror ( rc ) );
1692                 goto err_query_fw;
1693         }
1694         DBGC ( arbel, "Arbel %p firmware version %d.%d.%d\n", arbel,
1695                MLX_GET ( &fw, fw_rev_major ), MLX_GET ( &fw, fw_rev_minor ),
1696                MLX_GET ( &fw, fw_rev_subminor ) );
1697         fw_pages = MLX_GET ( &fw, fw_pages );
1698         log2_fw_pages = fls ( fw_pages - 1 );
1699         fw_pages = ( 1 << log2_fw_pages );
1700         DBGC ( arbel, "Arbel %p requires %d kB for firmware\n",
1701                arbel, ( fw_pages * 4 ) );
1702         eq_set_ci_base_addr =
1703                 ( ( (uint64_t) MLX_GET ( &fw, eq_set_ci_base_addr_h ) << 32 ) |
1704                   ( (uint64_t) MLX_GET ( &fw, eq_set_ci_base_addr_l ) ) );
1705         arbel->eq_ci_doorbells = ioremap ( eq_set_ci_base_addr, 0x200 );
1706
1707         /* Enable locally-attached memory.  Ignore failure; there may
1708          * be no attached memory.
1709          */
1710         arbel_cmd_enable_lam ( arbel, &lam );
1711
1712         /* Allocate firmware pages and map firmware area */
1713         fw_size = ( fw_pages * 4096 );
1714         arbel->firmware_area = umalloc ( fw_size * 2 );
1715         if ( ! arbel->firmware_area ) {
1716                 rc = -ENOMEM;
1717                 goto err_alloc_fa;
1718         }
1719         fw_base = ( user_to_phys ( arbel->firmware_area, fw_size ) &
1720                     ~( fw_size - 1 ) );
1721         DBGC ( arbel, "Arbel %p firmware area at physical [%lx,%lx)\n",
1722                arbel, fw_base, ( fw_base + fw_size ) );
1723         memset ( &map_fa, 0, sizeof ( map_fa ) );
1724         MLX_FILL_2 ( &map_fa, 3,
1725                      log2size, log2_fw_pages,
1726                      pa_l, ( fw_base >> 12 ) );
1727         if ( ( rc = arbel_cmd_map_fa ( arbel, &map_fa ) ) != 0 ) {
1728                 DBGC ( arbel, "Arbel %p could not map firmware: %s\n",
1729                        arbel, strerror ( rc ) );
1730                 goto err_map_fa;
1731         }
1732
1733         /* Start firmware */
1734         if ( ( rc = arbel_cmd_run_fw ( arbel ) ) != 0 ) {
1735                 DBGC ( arbel, "Arbel %p could not run firmware: %s\n",
1736                        arbel, strerror ( rc ) );
1737                 goto err_run_fw;
1738         }
1739
1740         DBGC ( arbel, "Arbel %p firmware started\n", arbel );
1741         return 0;
1742
1743  err_run_fw:
1744         arbel_cmd_unmap_fa ( arbel );
1745  err_map_fa:
1746         ufree ( arbel->firmware_area );
1747         arbel->firmware_area = UNULL;
1748  err_alloc_fa:
1749  err_query_fw:
1750         return rc;
1751 }
1752
1753 /**
1754  * Stop firmware running
1755  *
1756  * @v arbel             Arbel device
1757  */
1758 static void arbel_stop_firmware ( struct arbel *arbel ) {
1759         int rc;
1760
1761         if ( ( rc = arbel_cmd_unmap_fa ( arbel ) ) != 0 ) {
1762                 DBGC ( arbel, "Arbel %p FATAL could not stop firmware: %s\n",
1763                        arbel, strerror ( rc ) );
1764                 /* Leak memory and return; at least we avoid corruption */
1765                 return;
1766         }
1767         ufree ( arbel->firmware_area );
1768         arbel->firmware_area = UNULL;
1769 }
1770
1771 /***************************************************************************
1772  *
1773  * Infinihost Context Memory management
1774  *
1775  ***************************************************************************
1776  */
1777
1778 /**
1779  * Get device limits
1780  *
1781  * @v arbel             Arbel device
1782  * @ret rc              Return status code
1783  */
1784 static int arbel_get_limits ( struct arbel *arbel ) {
1785         struct arbelprm_query_dev_lim dev_lim;
1786         int rc;
1787
1788         if ( ( rc = arbel_cmd_query_dev_lim ( arbel, &dev_lim ) ) != 0 ) {
1789                 DBGC ( arbel, "Arbel %p could not get device limits: %s\n",
1790                        arbel, strerror ( rc ) );
1791                 return rc;
1792         }
1793
1794         arbel->limits.reserved_qps =
1795                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_qps ) );
1796         arbel->limits.qpc_entry_size = MLX_GET ( &dev_lim, qpc_entry_sz );
1797         arbel->limits.eqpc_entry_size = MLX_GET ( &dev_lim, eqpc_entry_sz );
1798         arbel->limits.reserved_srqs =
1799                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_srqs ) );
1800         arbel->limits.srqc_entry_size = MLX_GET ( &dev_lim, srq_entry_sz );
1801         arbel->limits.reserved_ees =
1802                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_ees ) );
1803         arbel->limits.eec_entry_size = MLX_GET ( &dev_lim, eec_entry_sz );
1804         arbel->limits.eeec_entry_size = MLX_GET ( &dev_lim, eeec_entry_sz );
1805         arbel->limits.reserved_cqs =
1806                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_cqs ) );
1807         arbel->limits.cqc_entry_size = MLX_GET ( &dev_lim, cqc_entry_sz );
1808         arbel->limits.reserved_eqs = MLX_GET ( &dev_lim, num_rsvd_eqs );
1809         arbel->limits.reserved_mtts =
1810                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_mtts ) );
1811         arbel->limits.mtt_entry_size = MLX_GET ( &dev_lim, mtt_entry_sz );
1812         arbel->limits.reserved_mrws =
1813                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_mrws ) );
1814         arbel->limits.mpt_entry_size = MLX_GET ( &dev_lim, mpt_entry_sz );
1815         arbel->limits.reserved_rdbs =
1816                 ( 1 << MLX_GET ( &dev_lim, log2_rsvd_rdbs ) );
1817         arbel->limits.eqc_entry_size = MLX_GET ( &dev_lim, eqc_entry_sz );
1818         arbel->limits.reserved_uars = MLX_GET ( &dev_lim, num_rsvd_uars );
1819
1820         return 0;
1821 }
1822
1823 /**
1824  * Get ICM usage
1825  *
1826  * @v log_num_entries   Log2 of the number of entries
1827  * @v entry_size        Entry size
1828  * @ret usage           Usage size in ICM
1829  */
1830 static size_t icm_usage ( unsigned int log_num_entries, size_t entry_size ) {
1831         size_t usage;
1832
1833         usage = ( ( 1 << log_num_entries ) * entry_size );
1834         usage = ( ( usage + 4095 ) & ~4095 );
1835         return usage;
1836 }
1837
1838 /**
1839  * Allocate ICM
1840  *
1841  * @v arbel             Arbel device
1842  * @v init_hca          INIT_HCA structure to fill in
1843  * @ret rc              Return status code
1844  */
1845 static int arbel_alloc_icm ( struct arbel *arbel,
1846                              struct arbelprm_init_hca *init_hca ) {
1847         struct arbelprm_scalar_parameter icm_size;
1848         struct arbelprm_scalar_parameter icm_aux_size;
1849         struct arbelprm_virtual_physical_mapping map_icm_aux;
1850         struct arbelprm_virtual_physical_mapping map_icm;
1851         union arbelprm_doorbell_record *db_rec;
1852         size_t icm_offset = 0;
1853         unsigned int log_num_qps, log_num_srqs, log_num_ees, log_num_cqs;
1854         unsigned int log_num_mtts, log_num_mpts, log_num_rdbs, log_num_eqs;
1855         int rc;
1856
1857         icm_offset = ( ( arbel->limits.reserved_uars + 1 ) << 12 );
1858
1859         /* Queue pair contexts */
1860         log_num_qps = fls ( arbel->limits.reserved_qps + ARBEL_MAX_QPS - 1 );
1861         MLX_FILL_2 ( init_hca, 13,
1862                      qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_l,
1863                      ( icm_offset >> 7 ),
1864                      qpc_eec_cqc_eqc_rdb_parameters.log_num_of_qp,
1865                      log_num_qps );
1866         DBGC ( arbel, "Arbel %p ICM QPC base = %zx\n", arbel, icm_offset );
1867         icm_offset += icm_usage ( log_num_qps, arbel->limits.qpc_entry_size );
1868
1869         /* Extended queue pair contexts */
1870         MLX_FILL_1 ( init_hca, 25,
1871                      qpc_eec_cqc_eqc_rdb_parameters.eqpc_base_addr_l,
1872                      icm_offset );
1873         DBGC ( arbel, "Arbel %p ICM EQPC base = %zx\n", arbel, icm_offset );
1874         //      icm_offset += icm_usage ( log_num_qps, arbel->limits.eqpc_entry_size );
1875         icm_offset += icm_usage ( log_num_qps, arbel->limits.qpc_entry_size );  
1876
1877         /* Shared receive queue contexts */
1878         log_num_srqs = fls ( arbel->limits.reserved_srqs - 1 );
1879         MLX_FILL_2 ( init_hca, 19,
1880                      qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_l,
1881                      ( icm_offset >> 5 ),
1882                      qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq,
1883                      log_num_srqs );
1884         DBGC ( arbel, "Arbel %p ICM SRQC base = %zx\n", arbel, icm_offset );
1885         icm_offset += icm_usage ( log_num_srqs, arbel->limits.srqc_entry_size );
1886
1887         /* End-to-end contexts */
1888         log_num_ees = fls ( arbel->limits.reserved_ees - 1 );
1889         MLX_FILL_2 ( init_hca, 17,
1890                      qpc_eec_cqc_eqc_rdb_parameters.eec_base_addr_l,
1891                      ( icm_offset >> 7 ),
1892                      qpc_eec_cqc_eqc_rdb_parameters.log_num_of_ee,
1893                      log_num_ees );
1894         DBGC ( arbel, "Arbel %p ICM EEC base = %zx\n", arbel, icm_offset );
1895         icm_offset += icm_usage ( log_num_ees, arbel->limits.eec_entry_size );
1896
1897         /* Extended end-to-end contexts */
1898         MLX_FILL_1 ( init_hca, 29,
1899                      qpc_eec_cqc_eqc_rdb_parameters.eeec_base_addr_l,
1900                      icm_offset );
1901         DBGC ( arbel, "Arbel %p ICM EEEC base = %zx\n", arbel, icm_offset );
1902         icm_offset += icm_usage ( log_num_ees, arbel->limits.eeec_entry_size );
1903
1904         /* Completion queue contexts */
1905         log_num_cqs = fls ( arbel->limits.reserved_cqs + ARBEL_MAX_CQS - 1 );
1906         MLX_FILL_2 ( init_hca, 21,
1907                      qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_l,
1908                      ( icm_offset >> 6 ),
1909                      qpc_eec_cqc_eqc_rdb_parameters.log_num_of_cq,
1910                      log_num_cqs );
1911         DBGC ( arbel, "Arbel %p ICM CQC base = %zx\n", arbel, icm_offset );
1912         icm_offset += icm_usage ( log_num_cqs, arbel->limits.cqc_entry_size );
1913
1914         /* Memory translation table */
1915         log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
1916         MLX_FILL_1 ( init_hca, 65,
1917                      tpt_parameters.mtt_base_addr_l, icm_offset );
1918         DBGC ( arbel, "Arbel %p ICM MTT base = %zx\n", arbel, icm_offset );
1919         icm_offset += icm_usage ( log_num_mtts, arbel->limits.mtt_entry_size );
1920
1921         /* Memory protection table */
1922         log_num_mpts = fls ( arbel->limits.reserved_mrws + 1 - 1 );
1923         MLX_FILL_1 ( init_hca, 61,
1924                      tpt_parameters.mpt_base_adr_l, icm_offset );
1925         MLX_FILL_1 ( init_hca, 62,
1926                      tpt_parameters.log_mpt_sz, log_num_mpts );
1927         DBGC ( arbel, "Arbel %p ICM MTT base = %zx\n", arbel, icm_offset );
1928         icm_offset += icm_usage ( log_num_mpts, arbel->limits.mpt_entry_size );
1929
1930         /* RDMA something or other */
1931         log_num_rdbs = fls ( arbel->limits.reserved_rdbs - 1 );
1932         MLX_FILL_1 ( init_hca, 37,
1933                      qpc_eec_cqc_eqc_rdb_parameters.rdb_base_addr_l,
1934                      icm_offset );
1935         DBGC ( arbel, "Arbel %p ICM RDB base = %zx\n", arbel, icm_offset );
1936         icm_offset += icm_usage ( log_num_rdbs, 32 );
1937
1938         /* Event queue contexts */
1939         log_num_eqs =  fls ( arbel->limits.reserved_eqs + ARBEL_MAX_EQS - 1 );
1940         MLX_FILL_2 ( init_hca, 33,
1941                      qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_l,
1942                      ( icm_offset >> 6 ),
1943                      qpc_eec_cqc_eqc_rdb_parameters.log_num_eq,
1944                      log_num_eqs );
1945         DBGC ( arbel, "Arbel %p ICM EQ base = %zx\n", arbel, icm_offset );
1946         icm_offset += ( ( 1 << log_num_eqs ) * arbel->limits.eqc_entry_size );
1947
1948         /* Multicast table */
1949         MLX_FILL_1 ( init_hca, 49,
1950                      multicast_parameters.mc_base_addr_l, icm_offset );
1951         MLX_FILL_1 ( init_hca, 52,
1952                      multicast_parameters.log_mc_table_entry_sz,
1953                      fls ( sizeof ( struct arbelprm_mgm_entry ) - 1 ) );
1954         MLX_FILL_1 ( init_hca, 53,
1955                      multicast_parameters.mc_table_hash_sz, 8 );
1956         MLX_FILL_1 ( init_hca, 54,
1957                      multicast_parameters.log_mc_table_sz, 3 );
1958         DBGC ( arbel, "Arbel %p ICM MC base = %zx\n", arbel, icm_offset );
1959         icm_offset += ( 8 * sizeof ( struct arbelprm_mgm_entry ) );
1960
1961         arbel->icm_len = icm_offset;
1962         arbel->icm_len = ( ( arbel->icm_len + 4095 ) & ~4095 );
1963
1964         /* Get ICM auxiliary area size */
1965         memset ( &icm_size, 0, sizeof ( icm_size ) );
1966         MLX_FILL_1 ( &icm_size, 1, value, arbel->icm_len );
1967         if ( ( rc = arbel_cmd_set_icm_size ( arbel, &icm_size,
1968                                              &icm_aux_size ) ) != 0 ) {
1969                 DBGC ( arbel, "Arbel %p could not set ICM size: %s\n",
1970                        arbel, strerror ( rc ) );
1971                 goto err_set_icm_size;
1972         }
1973         arbel->icm_aux_len = ( MLX_GET ( &icm_aux_size, value ) * 4096 );
1974
1975         /* Allocate ICM data and auxiliary area */
1976         DBGC ( arbel, "Arbel %p requires %zd kB ICM and %zd kB AUX ICM\n",
1977                arbel, ( arbel->icm_len / 1024 ),
1978                ( arbel->icm_aux_len / 1024 ) );
1979         arbel->icm = umalloc ( arbel->icm_len + arbel->icm_aux_len );
1980         if ( ! arbel->icm ) {
1981                 rc = -ENOMEM;
1982                 goto err_alloc;
1983         }
1984
1985         /* Map ICM auxiliary area */
1986         memset ( &map_icm_aux, 0, sizeof ( map_icm_aux ) );
1987         MLX_FILL_2 ( &map_icm_aux, 3,
1988                      log2size, fls ( ( arbel->icm_aux_len / 4096 ) - 1 ),
1989                      pa_l,
1990                      ( user_to_phys ( arbel->icm, arbel->icm_len ) >> 12 ) );
1991         if ( ( rc = arbel_cmd_map_icm_aux ( arbel, &map_icm_aux ) ) != 0 ) {
1992                 DBGC ( arbel, "Arbel %p could not map AUX ICM: %s\n",
1993                        arbel, strerror ( rc ) );
1994                 goto err_map_icm_aux;
1995         }
1996
1997         /* MAP ICM area */
1998         memset ( &map_icm, 0, sizeof ( map_icm ) );
1999         MLX_FILL_2 ( &map_icm, 3,
2000                      log2size, fls ( ( arbel->icm_len / 4096 ) - 1 ),
2001                      pa_l, ( user_to_phys ( arbel->icm, 0 ) >> 12 ) );
2002         if ( ( rc = arbel_cmd_map_icm ( arbel, &map_icm ) ) != 0 ) {
2003                 DBGC ( arbel, "Arbel %p could not map ICM: %s\n",
2004                        arbel, strerror ( rc ) );
2005                 goto err_map_icm;
2006         }
2007
2008         /* Initialise UAR context */
2009         arbel->db_rec = phys_to_virt ( user_to_phys ( arbel->icm, 0 ) +
2010                                        ( arbel->limits.reserved_uars *
2011                                          ARBEL_PAGE_SIZE ) );
2012         memset ( arbel->db_rec, 0, ARBEL_PAGE_SIZE );
2013         db_rec = &arbel->db_rec[ARBEL_GROUP_SEPARATOR_DOORBELL];
2014         MLX_FILL_1 ( &db_rec->qp, 1, res, ARBEL_UAR_RES_GROUP_SEP );
2015
2016         return 0;
2017
2018         arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / 4096 ) );
2019  err_map_icm:
2020         arbel_cmd_unmap_icm_aux ( arbel );
2021  err_map_icm_aux:
2022         ufree ( arbel->icm );
2023         arbel->icm = UNULL;
2024  err_alloc:
2025  err_set_icm_size:
2026         return rc;
2027 }
2028
2029 /**
2030  * Free ICM
2031  *
2032  * @v arbel             Arbel device
2033  */
2034 static void arbel_free_icm ( struct arbel *arbel ) {
2035         arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / 4096 ) );
2036         arbel_cmd_unmap_icm_aux ( arbel );
2037         ufree ( arbel->icm );
2038         arbel->icm = UNULL;
2039 }
2040
2041 /***************************************************************************
2042  *
2043  * PCI interface
2044  *
2045  ***************************************************************************
2046  */
2047
2048 /**
2049  * Set up memory protection table
2050  *
2051  * @v arbel             Arbel device
2052  * @ret rc              Return status code
2053  */
2054 static int arbel_setup_mpt ( struct arbel *arbel ) {
2055         struct arbelprm_mpt mpt;
2056         uint32_t key;
2057         int rc;
2058
2059         /* Derive key */
2060         key = ( arbel->limits.reserved_mrws | ARBEL_MKEY_PREFIX );
2061         arbel->reserved_lkey = ( ( key << 8 ) | ( key >> 24 ) );
2062
2063         /* Initialise memory protection table */
2064         memset ( &mpt, 0, sizeof ( mpt ) );
2065         MLX_FILL_4 ( &mpt, 0,
2066                      r_w, 1,
2067                      pa, 1,
2068                      lr, 1,
2069                      lw, 1 );
2070         MLX_FILL_1 ( &mpt, 2, mem_key, key );
2071         MLX_FILL_1 ( &mpt, 3, pd, ARBEL_GLOBAL_PD );
2072         MLX_FILL_1 ( &mpt, 6, reg_wnd_len_h, 0xffffffffUL );
2073         MLX_FILL_1 ( &mpt, 7, reg_wnd_len_l, 0xffffffffUL );
2074         if ( ( rc = arbel_cmd_sw2hw_mpt ( arbel, arbel->limits.reserved_mrws,
2075                                           &mpt ) ) != 0 ) {
2076                 DBGC ( arbel, "Arbel %p could not set up MPT: %s\n",
2077                        arbel, strerror ( rc ) );
2078                 return rc;
2079         }
2080
2081         return 0;
2082 }
2083         
2084 /**
2085  * Probe PCI device
2086  *
2087  * @v pci               PCI device
2088  * @v id                PCI ID
2089  * @ret rc              Return status code
2090  */
2091 static int arbel_probe ( struct pci_device *pci,
2092                          const struct pci_device_id *id __unused ) {
2093         struct arbel *arbel;
2094         struct ib_device *ibdev;
2095         struct arbelprm_init_hca init_hca;
2096         int i;
2097         int rc;
2098
2099         /* Allocate Arbel device */
2100         arbel = zalloc ( sizeof ( *arbel ) );
2101         if ( ! arbel ) {
2102                 rc = -ENOMEM;
2103                 goto err_alloc_arbel;
2104         }
2105         pci_set_drvdata ( pci, arbel );
2106
2107         /* Allocate Infiniband devices */
2108         for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) {
2109                 ibdev = alloc_ibdev ( 0 );
2110                 if ( ! ibdev ) {
2111                         rc = -ENOMEM;
2112                         goto err_alloc_ibdev;
2113                 }
2114                 arbel->ibdev[i] = ibdev;
2115                 ibdev->op = &arbel_ib_operations;
2116                 ibdev->dev = &pci->dev;
2117                 ibdev->port = ( ARBEL_PORT_BASE + i );
2118                 ib_set_drvdata ( ibdev, arbel );
2119         }
2120
2121         /* Fix up PCI device */
2122         adjust_pci_device ( pci );
2123
2124         /* Get PCI BARs */
2125         arbel->config = ioremap ( pci_bar_start ( pci, ARBEL_PCI_CONFIG_BAR ),
2126                                   ARBEL_PCI_CONFIG_BAR_SIZE );
2127         arbel->uar = ioremap ( ( pci_bar_start ( pci, ARBEL_PCI_UAR_BAR ) +
2128                                  ARBEL_PCI_UAR_IDX * ARBEL_PCI_UAR_SIZE ),
2129                                ARBEL_PCI_UAR_SIZE );
2130
2131         /* Allocate space for mailboxes */
2132         arbel->mailbox_in = malloc_dma ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN );
2133         if ( ! arbel->mailbox_in ) {
2134                 rc = -ENOMEM;
2135                 goto err_mailbox_in;
2136         }
2137         arbel->mailbox_out = malloc_dma ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN );
2138         if ( ! arbel->mailbox_out ) {
2139                 rc = -ENOMEM;
2140                 goto err_mailbox_out;
2141         }
2142
2143         /* Start firmware */
2144         if ( ( rc = arbel_start_firmware ( arbel ) ) != 0 )
2145                 goto err_start_firmware;
2146
2147         /* Get device limits */
2148         if ( ( rc = arbel_get_limits ( arbel ) ) != 0 )
2149                 goto err_get_limits;
2150
2151         /* Allocate ICM */
2152         memset ( &init_hca, 0, sizeof ( init_hca ) );
2153         if ( ( rc = arbel_alloc_icm ( arbel, &init_hca ) ) != 0 )
2154                 goto err_alloc_icm;
2155
2156         /* Initialise HCA */
2157         MLX_FILL_1 ( &init_hca, 74, uar_parameters.log_max_uars, 1 );
2158         if ( ( rc = arbel_cmd_init_hca ( arbel, &init_hca ) ) != 0 ) {
2159                 DBGC ( arbel, "Arbel %p could not initialise HCA: %s\n",
2160                        arbel, strerror ( rc ) );
2161                 goto err_init_hca;
2162         }
2163
2164         /* Set up memory protection */
2165         if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 )
2166                 goto err_setup_mpt;
2167
2168         /* Set up event queue */
2169         if ( ( rc = arbel_create_eq ( arbel ) ) != 0 )
2170                 goto err_create_eq;
2171
2172         /* Update MAD parameters */
2173         for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ )
2174                 ib_smc_update ( arbel->ibdev[i], arbel_mad );
2175
2176         /* Register Infiniband devices */
2177         for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) {
2178                 if ( ( rc = register_ibdev ( arbel->ibdev[i] ) ) != 0 ) {
2179                         DBGC ( arbel, "Arbel %p could not register IB "
2180                                "device: %s\n", arbel, strerror ( rc ) );
2181                         goto err_register_ibdev;
2182                 }
2183         }
2184
2185         return 0;
2186
2187         i = ARBEL_NUM_PORTS;
2188  err_register_ibdev:
2189         for ( i-- ; i >= 0 ; i-- )
2190                 unregister_ibdev ( arbel->ibdev[i] );
2191         arbel_destroy_eq ( arbel );
2192  err_create_eq:
2193  err_setup_mpt:
2194         arbel_cmd_close_hca ( arbel );
2195  err_init_hca:
2196         arbel_free_icm ( arbel );
2197  err_alloc_icm:
2198  err_get_limits:
2199         arbel_stop_firmware ( arbel );
2200  err_start_firmware:
2201         free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE );
2202  err_mailbox_out:
2203         free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
2204  err_mailbox_in:
2205         i = ARBEL_NUM_PORTS;
2206  err_alloc_ibdev:
2207         for ( i-- ; i >= 0 ; i-- )
2208                 ibdev_put ( arbel->ibdev[i] );
2209         free ( arbel );
2210  err_alloc_arbel:
2211         return rc;
2212 }
2213
2214 /**
2215  * Remove PCI device
2216  *
2217  * @v pci               PCI device
2218  */
2219 static void arbel_remove ( struct pci_device *pci ) {
2220         struct arbel *arbel = pci_get_drvdata ( pci );
2221         int i;
2222
2223         for ( i = ( ARBEL_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
2224                 unregister_ibdev ( arbel->ibdev[i] );
2225         arbel_destroy_eq ( arbel );
2226         arbel_cmd_close_hca ( arbel );
2227         arbel_free_icm ( arbel );
2228         arbel_stop_firmware ( arbel );
2229         arbel_stop_firmware ( arbel );
2230         free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE );
2231         free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
2232         for ( i = ( ARBEL_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
2233                 ibdev_put ( arbel->ibdev[i] );
2234         free ( arbel );
2235 }
2236
2237 static struct pci_device_id arbel_nics[] = {
2238         PCI_ROM ( 0x15b3, 0x6282, "mt25218", "MT25218 HCA driver", 0 ),
2239         PCI_ROM ( 0x15b3, 0x6274, "mt25204", "MT25204 HCA driver", 0 ),
2240 };
2241
2242 struct pci_driver arbel_driver __pci_driver = {
2243         .ids = arbel_nics,
2244         .id_count = ( sizeof ( arbel_nics ) / sizeof ( arbel_nics[0] ) ),
2245         .probe = arbel_probe,
2246         .remove = arbel_remove,
2247 };