Explorar el Código

First (working) draft of command interface.

tags/v0.9.3
Michael Brown hace 16 años
padre
commit
bf9bd93856
Se han modificado 2 ficheros con 159 adiciones y 4 borrados
  1. 27
    0
      src/drivers/net/mlx_ipoib/arbel.h
  2. 132
    4
      src/drivers/net/mlx_ipoib/mt25218.c

+ 27
- 0
src/drivers/net/mlx_ipoib/arbel.h Ver fichero

@@ -16,14 +16,34 @@
16 16
 #define ARBEL_OPCODE_RECV_ERROR		0xfe
17 17
 #define ARBEL_OPCODE_SEND_ERROR		0xff
18 18
 
19
+/*
20
+ * HCA commands
21
+ *
22
+ */
23
+
24
+#define ARBEL_HCR_BASE			0x80680
25
+#define ARBEL_HCR_REG(x)		( ARBEL_HCR_BASE + 4 * (x) )
26
+#define ARBEL_HCR_MAX_WAIT_MS		2000
27
+
28
+#define ARBEL_HCR_OPCODE_MASK		0x0000ffffUL
29
+#define ARBEL_HCR_IN_IMMEDIATE		0x00010000UL
30
+#define ARBEL_HCR_IN_MAILBOX		0x00020000UL
31
+#define ARBEL_HCR_OUT_IMMEDIATE		0x00040000UL
32
+#define ARBEL_HCR_OUT_MAILBOX		0x00080000UL
33
+
34
+#define ARBEL_HCR_OP_SW2HW_CQ		( 0x0016 | ARBEL_HCR_IN_MAILBOX )
35
+#define ARBEL_HCR_OP_NOP		( 0x0031 )
36
+
19 37
 /*
20 38
  * Wrapper structures for hardware datatypes
21 39
  *
22 40
  */
23 41
 
42
+struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_context );
24 43
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_queue_entry );
25 44
 struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
26 45
 struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
46
+struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
27 47
 struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
28 48
 struct MLX_DECLARE_STRUCT ( arbelprm_recv_wqe_segment_next );
29 49
 struct MLX_DECLARE_STRUCT ( arbelprm_send_doorbell );
@@ -126,6 +146,13 @@ struct arbel_completion_queue {
126 146
 
127 147
 /** An Arbel device */
128 148
 struct arbel {
149
+	/** Configuration registers */
150
+	void *config;
151
+	/** Command input mailbox */
152
+	void *mailbox_in;
153
+	/** Command output mailbox */
154
+	void *mailbox_out;
155
+
129 156
 	/** User Access Region */
130 157
 	void *uar;
131 158
 	/** Doorbell records */

+ 132
- 4
src/drivers/net/mlx_ipoib/mt25218.c Ver fichero

@@ -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;

Loading…
Cancelar
Guardar