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