|
@@ -22,6 +22,8 @@ Skeleton NIC driver for Etherboot
|
22
|
22
|
/* to get the interface to the body of the program */
|
23
|
23
|
#include "nic.h"
|
24
|
24
|
|
|
25
|
+#define CREATE_OWN 1
|
|
26
|
+
|
25
|
27
|
#include "mt25218_imp.c"
|
26
|
28
|
|
27
|
29
|
#include "arbel.h"
|
|
@@ -35,17 +37,25 @@ static const struct ib_gid arbel_no_gid = {
|
35
|
37
|
#define MLX_RX_MAX_FILL NUM_IPOIB_RCV_WQES
|
36
|
38
|
|
37
|
39
|
struct mlx_nic {
|
|
40
|
+#if ! CREATE_OWN
|
38
|
41
|
/** Queue pair handle */
|
39
|
42
|
udqp_t ipoib_qph;
|
40
|
|
- /** Broadcast Address Vector */
|
41
|
|
- ud_av_t bcast_av;
|
42
|
43
|
/** Send completion queue */
|
43
|
44
|
cq_t snd_cqh;
|
44
|
45
|
/** Receive completion queue */
|
45
|
46
|
cq_t rcv_cqh;
|
|
47
|
+#endif
|
|
48
|
+ /** Broadcast Address Vector */
|
|
49
|
+ ud_av_t bcast_av;
|
46
|
50
|
|
47
|
51
|
/** RX fill level */
|
48
|
52
|
unsigned int rx_fill;
|
|
53
|
+
|
|
54
|
+#if CREATE_OWN
|
|
55
|
+ struct ib_completion_queue *own_send_cq;
|
|
56
|
+ struct ib_completion_queue *own_recv_cq;
|
|
57
|
+ struct ib_queue_pair *own_qp;
|
|
58
|
+#endif
|
49
|
59
|
};
|
50
|
60
|
|
51
|
61
|
|
|
@@ -54,6 +64,8 @@ static struct io_buffer *static_ipoib_rx_ring[NUM_IPOIB_RCV_WQES];
|
54
|
64
|
|
55
|
65
|
static struct arbel static_arbel;
|
56
|
66
|
|
|
67
|
+#if ! CREATE_OWN
|
|
68
|
+
|
57
|
69
|
static struct arbel_completion_queue static_arbel_ipoib_send_cq = {
|
58
|
70
|
.ci_doorbell_idx = IPOIB_SND_CQ_CI_DB_IDX,
|
59
|
71
|
};
|
|
@@ -104,6 +116,8 @@ static struct ib_queue_pair static_ipoib_qp = {
|
104
|
116
|
.dev_priv = &static_arbel_ipoib_qp,
|
105
|
117
|
};
|
106
|
118
|
|
|
119
|
+#endif
|
|
120
|
+
|
107
|
121
|
|
108
|
122
|
static struct ib_device static_ibdev = {
|
109
|
123
|
.dev_priv = &static_arbel,
|
|
@@ -157,7 +171,13 @@ static int mlx_transmit_direct ( struct net_device *netdev,
|
157
|
171
|
};
|
158
|
172
|
memcpy ( &av.gid, ( ( void * ) bav ) + 16, 16 );
|
159
|
173
|
|
160
|
|
- rc = arbel_post_send ( &static_ibdev, &static_ipoib_qp, &av, iobuf );
|
|
174
|
+ rc = arbel_post_send ( &static_ibdev,
|
|
175
|
+#if CREATE_OWN
|
|
176
|
+ mlx->own_qp,
|
|
177
|
+#else
|
|
178
|
+ &static_ipoib_qp,
|
|
179
|
+#endif
|
|
180
|
+ &av, iobuf );
|
161
|
181
|
|
162
|
182
|
return rc;
|
163
|
183
|
}
|
|
@@ -212,7 +232,11 @@ static void mlx_refill_rx ( struct net_device *netdev ) {
|
212
|
232
|
break;
|
213
|
233
|
DBG ( "Posting RX buffer %p:\n", iobuf );
|
214
|
234
|
if ( ( rc = arbel_post_recv ( &static_ibdev,
|
|
235
|
+#if CREATE_OWN
|
|
236
|
+ mlx->own_qp,
|
|
237
|
+#else
|
215
|
238
|
&static_ipoib_qp,
|
|
239
|
+#endif
|
216
|
240
|
iobuf ) ) != 0 ) {
|
217
|
241
|
free_iob ( iobuf );
|
218
|
242
|
break;
|
|
@@ -244,9 +268,19 @@ static void mlx_poll ( struct net_device *netdev ) {
|
244
|
268
|
}
|
245
|
269
|
|
246
|
270
|
/* Poll completion queues */
|
247
|
|
- arbel_poll_cq ( &static_ibdev, &static_ipoib_send_cq,
|
|
271
|
+ arbel_poll_cq ( &static_ibdev,
|
|
272
|
+#if CREATE_OWN
|
|
273
|
+ mlx->own_send_cq,
|
|
274
|
+#else
|
|
275
|
+ &static_ipoib_send_cq,
|
|
276
|
+#endif
|
248
|
277
|
temp_complete_send, temp_complete_recv );
|
249
|
|
- arbel_poll_cq ( &static_ibdev, &static_ipoib_recv_cq,
|
|
278
|
+ arbel_poll_cq ( &static_ibdev,
|
|
279
|
+#if CREATE_OWN
|
|
280
|
+ mlx->own_recv_cq,
|
|
281
|
+#else
|
|
282
|
+ &static_ipoib_recv_cq,
|
|
283
|
+#endif
|
250
|
284
|
temp_complete_send, temp_complete_recv );
|
251
|
285
|
|
252
|
286
|
mlx_refill_rx ( netdev );
|
|
@@ -406,6 +440,15 @@ static int arbel_cmd ( struct arbel *arbel, unsigned long command,
|
406
|
440
|
opcode_modifier, op_mod,
|
407
|
441
|
go, 1 );
|
408
|
442
|
|
|
443
|
+ DBG_HD ( &hcr, sizeof ( hcr ) );
|
|
444
|
+ if ( in_len ) {
|
|
445
|
+ size_t dump_len = in_len;
|
|
446
|
+ if ( dump_len > 256 )
|
|
447
|
+ dump_len = 256;
|
|
448
|
+ DBG ( "Input:\n" );
|
|
449
|
+ DBG_HD ( in, dump_len );
|
|
450
|
+ }
|
|
451
|
+
|
409
|
452
|
/* Issue command */
|
410
|
453
|
for ( i = 0 ; i < ( sizeof ( hcr ) / sizeof ( hcr.u.dwords[0] ) ) ;
|
411
|
454
|
i++ ) {
|
|
@@ -436,6 +479,14 @@ static int arbel_cmd ( struct arbel *arbel, unsigned long command,
|
436
|
479
|
hcr.u.dwords[4] = readl ( arbel->config + ARBEL_HCR_REG ( 4 ) );
|
437
|
480
|
memcpy ( out, out_buffer, out_len );
|
438
|
481
|
|
|
482
|
+ if ( out_len ) {
|
|
483
|
+ size_t dump_len = out_len;
|
|
484
|
+ if ( dump_len > 256 )
|
|
485
|
+ dump_len = 256;
|
|
486
|
+ DBG ( "Output:\n" );
|
|
487
|
+ DBG_HD ( out, dump_len );
|
|
488
|
+ }
|
|
489
|
+
|
439
|
490
|
return 0;
|
440
|
491
|
}
|
441
|
492
|
|
|
@@ -698,7 +749,9 @@ static int arbel_create_recv_wq ( struct arbel_recv_work_queue *arbel_recv_wq,
|
698
|
749
|
struct arbelprm_recv_wqe *wqe;
|
699
|
750
|
struct arbelprm_recv_wqe *next_wqe;
|
700
|
751
|
unsigned int wqe_idx_mask;
|
|
752
|
+ size_t nds;
|
701
|
753
|
unsigned int i;
|
|
754
|
+ unsigned int j;
|
702
|
755
|
|
703
|
756
|
/* Allocate work queue */
|
704
|
757
|
arbel_recv_wq->wqe_size = ( num_wqes *
|
|
@@ -711,11 +764,19 @@ static int arbel_create_recv_wq ( struct arbel_recv_work_queue *arbel_recv_wq,
|
711
|
764
|
|
712
|
765
|
/* Link work queue entries */
|
713
|
766
|
wqe_idx_mask = ( num_wqes - 1 );
|
|
767
|
+ nds = ( ( offsetof ( typeof ( *wqe ), data ) +
|
|
768
|
+ sizeof ( wqe->data[0] ) ) >> 4 );
|
714
|
769
|
for ( i = 0 ; i < num_wqes ; i++ ) {
|
715
|
770
|
wqe = &arbel_recv_wq->wqe[i].recv;
|
716
|
771
|
next_wqe = &arbel_recv_wq->wqe[( i + 1 ) & wqe_idx_mask].recv;
|
717
|
772
|
MLX_FILL_1 ( &wqe->next, 0, nda_31_6,
|
718
|
773
|
( virt_to_bus ( next_wqe ) >> 6 ) );
|
|
774
|
+ MLX_FILL_1 ( &wqe->next, 1, nds, ( sizeof ( *wqe ) / 16 ) );
|
|
775
|
+ for ( j = 0 ; ( ( ( void * ) &wqe->data[j] ) <
|
|
776
|
+ ( ( void * ) ( wqe + 1 ) ) ) ; j++ ) {
|
|
777
|
+ MLX_FILL_1 ( &wqe->data[j], 1,
|
|
778
|
+ l_key, ARBEL_INVALID_LKEY );
|
|
779
|
+ }
|
719
|
780
|
}
|
720
|
781
|
|
721
|
782
|
return 0;
|
|
@@ -787,10 +848,10 @@ static int arbel_create_qp ( struct ib_device *ibdev,
|
787
|
848
|
qpc_eec_data.msg_max, 11 /* 2^11 = 2048 */,
|
788
|
849
|
qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ),
|
789
|
850
|
qpc_eec_data.log_rq_stride,
|
790
|
|
- ( fls ( sizeof ( arbel_qp->send.wqe[0] ) - 1 ) - 4 ),
|
|
851
|
+ ( fls ( sizeof ( arbel_qp->recv.wqe[0] ) - 1 ) - 4 ),
|
791
|
852
|
qpc_eec_data.log_sq_size, fls ( qp->send.num_wqes - 1 ),
|
792
|
853
|
qpc_eec_data.log_sq_stride,
|
793
|
|
- ( fls ( sizeof ( arbel_qp->recv.wqe[0] ) - 1 ) - 4 ) );
|
|
854
|
+ ( fls ( sizeof ( arbel_qp->send.wqe[0] ) - 1 ) - 4 ) );
|
794
|
855
|
MLX_FILL_1 ( &qpctx, 5,
|
795
|
856
|
qpc_eec_data.usr_page, arbel->limits.reserved_uars );
|
796
|
857
|
MLX_FILL_1 ( &qpctx, 10, qpc_eec_data.primary_address_path.port_number,
|
|
@@ -976,6 +1037,7 @@ static int arbel_post_send ( struct ib_device *ibdev,
|
976
|
1037
|
MLX_FILL_1 ( &wqe->ud, 8, destination_qp, av->dest_qp );
|
977
|
1038
|
MLX_FILL_1 ( &wqe->ud, 9, q_key, av->qkey );
|
978
|
1039
|
MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_len ( iobuf ) );
|
|
1040
|
+ MLX_FILL_1 ( &wqe->data[0], 1, l_key, arbel->reserved_lkey );
|
979
|
1041
|
MLX_FILL_1 ( &wqe->data[0], 3,
|
980
|
1042
|
local_address_l, virt_to_bus ( iobuf->data ) );
|
981
|
1043
|
|
|
@@ -1249,6 +1311,7 @@ static int arbel_probe ( struct pci_device *pci,
|
1249
|
1311
|
/* Initialise hardware */
|
1250
|
1312
|
if ( ( rc = ib_driver_init ( pci, &qph ) ) != 0 )
|
1251
|
1313
|
goto err_ipoib_init;
|
|
1314
|
+#if ! CREATE_OWN
|
1252
|
1315
|
mlx->ipoib_qph = qph;
|
1253
|
1316
|
mlx->bcast_av = ib_data.bcast_av;
|
1254
|
1317
|
mlx->snd_cqh = ib_data.ipoib_snd_cq;
|
|
@@ -1256,6 +1319,7 @@ static int arbel_probe ( struct pci_device *pci,
|
1256
|
1319
|
mac = ( ( struct ib_mac * ) netdev->ll_addr );
|
1257
|
1320
|
mac->qpn = htonl ( ib_get_qpn ( mlx->ipoib_qph ) );
|
1258
|
1321
|
memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
|
|
1322
|
+#endif
|
1259
|
1323
|
|
1260
|
1324
|
/* Hack up IB structures */
|
1261
|
1325
|
arbel->config = memfree_pci_dev.cr_space;
|
|
@@ -1265,6 +1329,7 @@ static int arbel_probe ( struct pci_device *pci,
|
1265
|
1329
|
arbel->db_rec = dev_ib_data.uar_context_base;
|
1266
|
1330
|
arbel->reserved_lkey = dev_ib_data.mkey;
|
1267
|
1331
|
arbel->eqn = dev_ib_data.eq.eqn;
|
|
1332
|
+#if ! CREATE_OWN
|
1268
|
1333
|
static_arbel_ipoib_qp.send.wqe =
|
1269
|
1334
|
( ( struct udqp_st * ) qph )->snd_wq;
|
1270
|
1335
|
static_arbel_ipoib_qp.recv.wqe =
|
|
@@ -1279,6 +1344,7 @@ static int arbel_probe ( struct pci_device *pci,
|
1279
|
1344
|
&static_ipoib_send_cq.work_queues );
|
1280
|
1345
|
list_add ( &static_ipoib_qp.recv.list,
|
1281
|
1346
|
&static_ipoib_recv_cq.work_queues );
|
|
1347
|
+#endif
|
1282
|
1348
|
static_ibdev.op = &arbel_ib_operations;
|
1283
|
1349
|
|
1284
|
1350
|
/* Get device limits */
|
|
@@ -1293,12 +1359,40 @@ static int arbel_probe ( struct pci_device *pci,
|
1293
|
1359
|
arbel->limits.reserved_qps =
|
1294
|
1360
|
( 1 << MLX_GET ( &dev_lim, log2_rsvd_qps ) );
|
1295
|
1361
|
|
|
1362
|
+#if CREATE_OWN
|
|
1363
|
+ struct ib_device *ibdev = &static_ibdev;
|
|
1364
|
+ mlx->own_send_cq = ib_create_cq ( ibdev, 32 );
|
|
1365
|
+ if ( ! mlx->own_send_cq ) {
|
|
1366
|
+ DBG ( "Could not create send CQ\n" );
|
|
1367
|
+ return -EIO;
|
|
1368
|
+ }
|
|
1369
|
+ mlx->own_recv_cq = ib_create_cq ( ibdev, 32 );
|
|
1370
|
+ if ( ! mlx->own_recv_cq ) {
|
|
1371
|
+ DBG ( "Could not create send CQ\n" );
|
|
1372
|
+ return -EIO;
|
|
1373
|
+ }
|
|
1374
|
+ mlx->own_qp = ib_create_qp ( ibdev, NUM_IPOIB_SND_WQES,
|
|
1375
|
+ mlx->own_send_cq, NUM_IPOIB_RCV_WQES,
|
|
1376
|
+ mlx->own_recv_cq, ipoib_qkey );
|
|
1377
|
+ if ( ! mlx->own_qp ) {
|
|
1378
|
+ DBG ( "Could not create QP\n" );
|
|
1379
|
+ return -EIO;
|
|
1380
|
+ }
|
|
1381
|
+ mlx->own_qp->owner_priv = netdev;
|
|
1382
|
+
|
|
1383
|
+ mac = ( ( struct ib_mac * ) netdev->ll_addr );
|
|
1384
|
+ mac->qpn = htonl ( mlx->own_qp->qpn );
|
|
1385
|
+ memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
|
|
1386
|
+#endif
|
|
1387
|
+
|
|
1388
|
+#if 0
|
1296
|
1389
|
DBG ( "MADS SND CQN = %#lx\n", dev_ib_data.mads_qp.snd_cq.cqn );
|
1297
|
1390
|
struct ib_completion_queue *test_cq;
|
1298
|
1391
|
test_cq = ib_create_cq ( &static_ibdev, 32 );
|
1299
|
1392
|
if ( test_cq ) {
|
1300
|
1393
|
DBG ( "Woot: create_cq() passed!\n" );
|
1301
|
1394
|
}
|
|
1395
|
+#endif
|
1302
|
1396
|
|
1303
|
1397
|
/* Register network device */
|
1304
|
1398
|
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|