|
@@ -26,6 +26,11 @@ Skeleton NIC driver for Etherboot
|
26
|
26
|
#include "arbel.h"
|
27
|
27
|
|
28
|
28
|
|
|
29
|
+static const struct ib_gid arbel_no_gid = {
|
|
30
|
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }
|
|
31
|
+};
|
|
32
|
+
|
|
33
|
+
|
29
|
34
|
#define MLX_RX_MAX_FILL NUM_IPOIB_RCV_WQES
|
30
|
35
|
|
31
|
36
|
struct mlx_nic {
|
|
@@ -263,11 +268,121 @@ static struct net_device_operations mlx_operations = {
|
263
|
268
|
.irq = mlx_irq,
|
264
|
269
|
};
|
265
|
270
|
|
|
271
|
+/**
|
|
272
|
+ * Wait for Arbel command completion
|
|
273
|
+ *
|
|
274
|
+ * @v arbel Arbel device
|
|
275
|
+ * @ret rc Return status code
|
|
276
|
+ */
|
|
277
|
+static int arbel_command_wait ( struct arbel *arbel,
|
|
278
|
+ struct arbelprm_hca_command_register *hcr ) {
|
|
279
|
+ unsigned int wait;
|
|
280
|
+
|
|
281
|
+ for ( wait = ARBEL_HCR_MAX_WAIT_MS ; wait ; wait-- ) {
|
|
282
|
+ hcr->u.dwords[6] =
|
|
283
|
+ readl ( arbel->config + ARBEL_HCR_REG ( 6 ) );
|
|
284
|
+ if ( MLX_GET ( hcr, go ) == 0 )
|
|
285
|
+ return 0;
|
|
286
|
+ mdelay ( 1 );
|
|
287
|
+ }
|
|
288
|
+ return -EBUSY;
|
|
289
|
+}
|
266
|
290
|
|
|
291
|
+/**
|
|
292
|
+ * Issue HCA command
|
|
293
|
+ *
|
|
294
|
+ * @v arbel Arbel device
|
|
295
|
+ * @v op_fl Opcode (plus implied flags)
|
|
296
|
+ * @v op_mod Opcode modifier (0 if no modifier applicable)
|
|
297
|
+ * @v in_param Input parameter
|
|
298
|
+ * @v in_param_len Input parameter length
|
|
299
|
+ * @v in_mod Input modifier (0 if no modifier applicable)
|
|
300
|
+ * @v out_param Output parameter
|
|
301
|
+ * @ret rc Return status code
|
|
302
|
+ */
|
|
303
|
+static int arbel_command ( struct arbel *arbel, unsigned int op_fl,
|
|
304
|
+ unsigned int op_mod, const void *in_param,
|
|
305
|
+ size_t in_param_len, unsigned int in_mod,
|
|
306
|
+ void *out_param, size_t out_param_len ) {
|
|
307
|
+ struct arbelprm_hca_command_register hcr;
|
|
308
|
+ unsigned int status;
|
|
309
|
+ unsigned int i;
|
|
310
|
+ int rc;
|
|
311
|
+
|
|
312
|
+ /* Check that HCR is free */
|
|
313
|
+ if ( ( rc = arbel_command_wait ( arbel, &hcr ) ) != 0 ) {
|
|
314
|
+ DBGC ( arbel, "Arbel %p command interface locked\n", arbel );
|
|
315
|
+ return rc;
|
|
316
|
+ }
|
|
317
|
+
|
|
318
|
+ /* Prepare HCR */
|
|
319
|
+ memset ( &hcr, 0, sizeof ( hcr ) );
|
|
320
|
+ if ( op_fl & ARBEL_HCR_IN_IMMEDIATE ) {
|
|
321
|
+ memcpy ( &hcr.u.dwords[0], in_param, 8 );
|
|
322
|
+ } else if ( op_fl & ARBEL_HCR_IN_MAILBOX ) {
|
|
323
|
+ memcpy ( arbel->mailbox_in, in_param, in_param_len );
|
|
324
|
+ MLX_FILL_1 ( &hcr, 1, in_param_l,
|
|
325
|
+ virt_to_bus ( arbel->mailbox_in ) );
|
|
326
|
+ }
|
|
327
|
+ MLX_FILL_1 ( &hcr, 2, input_modifier, in_mod );
|
|
328
|
+ if ( op_fl & ARBEL_HCR_OUT_MAILBOX ) {
|
|
329
|
+ MLX_FILL_1 ( &hcr, 4, out_param_l,
|
|
330
|
+ virt_to_bus ( arbel->mailbox_out ) );
|
|
331
|
+ }
|
|
332
|
+ MLX_FILL_3 ( &hcr, 6,
|
|
333
|
+ opcode, ( op_fl & ARBEL_HCR_OPCODE_MASK ),
|
|
334
|
+ opcode_modifier, op_mod,
|
|
335
|
+ go, 1 );
|
|
336
|
+
|
|
337
|
+ /* Issue command */
|
|
338
|
+ for ( i = 0 ; i < ( sizeof ( hcr ) / sizeof ( hcr.u.dwords[0] ) ) ;
|
|
339
|
+ i++ ) {
|
|
340
|
+ writel ( hcr.u.dwords[i],
|
|
341
|
+ arbel->config + ARBEL_HCR_REG ( i ) );
|
|
342
|
+ barrier();
|
|
343
|
+ }
|
|
344
|
+
|
|
345
|
+ /* Wait for command completion */
|
|
346
|
+ if ( ( rc = arbel_command_wait ( arbel, &hcr ) ) != 0 ) {
|
|
347
|
+ DBGC ( arbel, "Arbel %p timed out waiting for command:\n",
|
|
348
|
+ arbel );
|
|
349
|
+ DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
|
|
350
|
+ return rc;
|
|
351
|
+ }
|
|
352
|
+
|
|
353
|
+ /* Check command status */
|
|
354
|
+ status = MLX_GET ( &hcr, status );
|
|
355
|
+ if ( status != 0 ) {
|
|
356
|
+ DBGC ( arbel, "Arbel %p command failed with status %02x:\n",
|
|
357
|
+ arbel, status );
|
|
358
|
+ DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
|
|
359
|
+ return -EIO;
|
|
360
|
+ }
|
|
361
|
+
|
|
362
|
+ /* Read output parameters, if any */
|
|
363
|
+ hcr.u.dwords[3] = readl ( arbel->config + ARBEL_HCR_REG ( 3 ) );
|
|
364
|
+ hcr.u.dwords[4] = readl ( arbel->config + ARBEL_HCR_REG ( 4 ) );
|
|
365
|
+ if ( op_fl & ARBEL_HCR_OUT_IMMEDIATE ) {
|
|
366
|
+ memcpy ( out_param, &hcr.u.dwords[3], 8 );
|
|
367
|
+ } else if ( op_fl & ARBEL_HCR_OUT_MAILBOX ) {
|
|
368
|
+ memcpy ( out_param, arbel->mailbox_out, out_param_len );
|
|
369
|
+ }
|
|
370
|
+
|
|
371
|
+ return 0;
|
|
372
|
+}
|
|
373
|
+
|
|
374
|
+/**
|
|
375
|
+ * Create completion queue
|
|
376
|
+ *
|
|
377
|
+ * @v ibdev Infiniband device
|
|
378
|
+ * @v
|
|
379
|
+ */
|
|
380
|
+static int arbel_create_cq ( struct ib_device *ibdev ) {
|
|
381
|
+ struct arbelprm_completion_queue_context *cqctx;
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+}
|
267
|
385
|
|
268
|
|
-static struct ib_gid arbel_no_gid = {
|
269
|
|
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 }
|
270
|
|
-};
|
271
|
386
|
|
272
|
387
|
/**
|
273
|
388
|
* Ring doorbell register in UAR
|
|
@@ -310,7 +425,7 @@ static int arbel_post_send ( struct ib_device *ibdev,
|
310
|
425
|
struct arbelprm_ud_send_wqe *wqe;
|
311
|
426
|
union arbelprm_doorbell_record *db_rec;
|
312
|
427
|
union arbelprm_doorbell_register db_reg;
|
313
|
|
- struct ib_gid *gid;
|
|
428
|
+ const struct ib_gid *gid;
|
314
|
429
|
unsigned int wqe_idx_mask;
|
315
|
430
|
size_t nds;
|
316
|
431
|
|
|
@@ -616,6 +731,9 @@ static int arbel_probe ( struct pci_device *pci,
|
616
|
731
|
memcpy ( &mac->gid, ib_data.port_gid.raw, sizeof ( mac->gid ) );
|
617
|
732
|
|
618
|
733
|
/* Hack up IB structures */
|
|
734
|
+ static_arbel.config = memfree_pci_dev.cr_space;
|
|
735
|
+ static_arbel.mailbox_in = dev_buffers_p->inprm_buf;
|
|
736
|
+ static_arbel.mailbox_out = dev_buffers_p->outprm_buf;
|
619
|
737
|
static_arbel.uar = memfree_pci_dev.uar;
|
620
|
738
|
static_arbel.db_rec = dev_ib_data.uar_context_base;
|
621
|
739
|
static_arbel.reserved_lkey = dev_ib_data.mkey;
|
|
@@ -634,6 +752,16 @@ static int arbel_probe ( struct pci_device *pci,
|
634
|
752
|
list_add ( &static_ipoib_qp.recv.list,
|
635
|
753
|
&static_ipoib_recv_cq.work_queues );
|
636
|
754
|
|
|
755
|
+ uint8_t buf[512];
|
|
756
|
+ memset ( buf, 0xaa, sizeof ( buf ) );
|
|
757
|
+ if ( ( rc = arbel_command ( &static_arbel,
|
|
758
|
+ ( 0x03 | ARBEL_HCR_OUT_MAILBOX ), 0,
|
|
759
|
+ NULL, 0, 0, buf, 256 ) ) != 0 ) {
|
|
760
|
+ DBG ( "QUERY_DEV_LIM failed: %s\n", strerror ( rc ) );
|
|
761
|
+ }
|
|
762
|
+ DBG ( "Device limits:\n ");
|
|
763
|
+ DBG_HD ( &buf[0], sizeof ( buf ) );
|
|
764
|
+
|
637
|
765
|
/* Register network device */
|
638
|
766
|
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|
639
|
767
|
goto err_register_netdev;
|