|
@@ -268,14 +268,21 @@ static struct net_device_operations mlx_operations = {
|
268
|
268
|
.irq = mlx_irq,
|
269
|
269
|
};
|
270
|
270
|
|
|
271
|
+/***************************************************************************
|
|
272
|
+ *
|
|
273
|
+ * HCA commands
|
|
274
|
+ *
|
|
275
|
+ ***************************************************************************
|
|
276
|
+ */
|
|
277
|
+
|
271
|
278
|
/**
|
272
|
279
|
* Wait for Arbel command completion
|
273
|
280
|
*
|
274
|
281
|
* @v arbel Arbel device
|
275
|
282
|
* @ret rc Return status code
|
276
|
283
|
*/
|
277
|
|
-static int arbel_command_wait ( struct arbel *arbel,
|
278
|
|
- struct arbelprm_hca_command_register *hcr ) {
|
|
284
|
+static int arbel_cmd_wait ( struct arbel *arbel,
|
|
285
|
+ struct arbelprm_hca_command_register *hcr ) {
|
279
|
286
|
unsigned int wait;
|
280
|
287
|
|
281
|
288
|
for ( wait = ARBEL_HCR_MAX_WAIT_MS ; wait ; wait-- ) {
|
|
@@ -292,45 +299,54 @@ static int arbel_command_wait ( struct arbel *arbel,
|
292
|
299
|
* Issue HCA command
|
293
|
300
|
*
|
294
|
301
|
* @v arbel Arbel device
|
295
|
|
- * @v op_fl Opcode (plus implied flags)
|
|
302
|
+ * @v command Command opcode, flags and input/output lengths
|
296
|
303
|
* @v op_mod Opcode modifier (0 if no modifier applicable)
|
297
|
|
- * @v in_param Input parameter
|
298
|
|
- * @v in_param_len Input parameter length
|
|
304
|
+ * @v in Input parameters
|
299
|
305
|
* @v in_mod Input modifier (0 if no modifier applicable)
|
300
|
|
- * @v out_param Output parameter
|
|
306
|
+ * @v out Output parameters
|
301
|
307
|
* @ret rc Return status code
|
302
|
308
|
*/
|
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 ) {
|
|
309
|
+static int arbel_cmd ( struct arbel *arbel, unsigned long command,
|
|
310
|
+ unsigned int op_mod, const void *in,
|
|
311
|
+ unsigned int in_mod, void *out ) {
|
307
|
312
|
struct arbelprm_hca_command_register hcr;
|
|
313
|
+ unsigned int opcode = ARBEL_HCR_OPCODE ( command );
|
|
314
|
+ size_t in_len = ARBEL_HCR_IN_LEN ( command );
|
|
315
|
+ size_t out_len = ARBEL_HCR_OUT_LEN ( command );
|
|
316
|
+ void *in_buffer;
|
|
317
|
+ void *out_buffer;
|
308
|
318
|
unsigned int status;
|
309
|
319
|
unsigned int i;
|
310
|
320
|
int rc;
|
311
|
321
|
|
|
322
|
+ DBGC ( arbel, "Arbel %p command %02x in %zx%s out %zx%s\n",
|
|
323
|
+ arbel, opcode, in_len,
|
|
324
|
+ ( ( command & ARBEL_HCR_IN_MBOX ) ? "(mbox)" : "" ), out_len,
|
|
325
|
+ ( ( command & ARBEL_HCR_OUT_MBOX ) ? "(mbox)" : "" ) );
|
|
326
|
+
|
312
|
327
|
/* Check that HCR is free */
|
313
|
|
- if ( ( rc = arbel_command_wait ( arbel, &hcr ) ) != 0 ) {
|
|
328
|
+ if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
|
314
|
329
|
DBGC ( arbel, "Arbel %p command interface locked\n", arbel );
|
315
|
330
|
return rc;
|
316
|
331
|
}
|
317
|
332
|
|
318
|
333
|
/* Prepare HCR */
|
319
|
334
|
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 ) );
|
|
335
|
+ in_buffer = &hcr.u.dwords[0];
|
|
336
|
+ if ( in_len && ( command & ARBEL_HCR_IN_MBOX ) ) {
|
|
337
|
+ in_buffer = arbel->mailbox_in;
|
|
338
|
+ MLX_FILL_1 ( &hcr, 1, in_param_l, virt_to_bus ( in_buffer ) );
|
326
|
339
|
}
|
|
340
|
+ memcpy ( in_buffer, in, in_len );
|
327
|
341
|
MLX_FILL_1 ( &hcr, 2, input_modifier, in_mod );
|
328
|
|
- if ( op_fl & ARBEL_HCR_OUT_MAILBOX ) {
|
|
342
|
+ out_buffer = &hcr.u.dwords[3];
|
|
343
|
+ if ( out_len && ( command & ARBEL_HCR_OUT_MBOX ) ) {
|
|
344
|
+ out_buffer = arbel->mailbox_out;
|
329
|
345
|
MLX_FILL_1 ( &hcr, 4, out_param_l,
|
330
|
|
- virt_to_bus ( arbel->mailbox_out ) );
|
|
346
|
+ virt_to_bus ( out_buffer ) );
|
331
|
347
|
}
|
332
|
348
|
MLX_FILL_3 ( &hcr, 6,
|
333
|
|
- opcode, ( op_fl & ARBEL_HCR_OPCODE_MASK ),
|
|
349
|
+ opcode, opcode,
|
334
|
350
|
opcode_modifier, op_mod,
|
335
|
351
|
go, 1 );
|
336
|
352
|
|
|
@@ -343,7 +359,7 @@ static int arbel_command ( struct arbel *arbel, unsigned int op_fl,
|
343
|
359
|
}
|
344
|
360
|
|
345
|
361
|
/* Wait for command completion */
|
346
|
|
- if ( ( rc = arbel_command_wait ( arbel, &hcr ) ) != 0 ) {
|
|
362
|
+ if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
|
347
|
363
|
DBGC ( arbel, "Arbel %p timed out waiting for command:\n",
|
348
|
364
|
arbel );
|
349
|
365
|
DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
|
|
@@ -362,15 +378,19 @@ static int arbel_command ( struct arbel *arbel, unsigned int op_fl,
|
362
|
378
|
/* Read output parameters, if any */
|
363
|
379
|
hcr.u.dwords[3] = readl ( arbel->config + ARBEL_HCR_REG ( 3 ) );
|
364
|
380
|
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
|
|
- }
|
|
381
|
+ memcpy ( out, out_buffer, out_len );
|
370
|
382
|
|
371
|
383
|
return 0;
|
372
|
384
|
}
|
373
|
385
|
|
|
386
|
+static int arbel_cmd_query_dev_lim ( struct arbel *arbel,
|
|
387
|
+ struct arbelprm_query_dev_lim *out ) {
|
|
388
|
+ return arbel_cmd ( arbel,
|
|
389
|
+ ARBEL_HCR_OUT_CMD ( ARBEL_HCR_QUERY_DEV_LIM,
|
|
390
|
+ 1, sizeof ( *out ) ),
|
|
391
|
+ 0, NULL, 0, out );
|
|
392
|
+}
|
|
393
|
+
|
374
|
394
|
/**
|
375
|
395
|
* Create completion queue
|
376
|
396
|
*
|
|
@@ -752,15 +772,14 @@ static int arbel_probe ( struct pci_device *pci,
|
752
|
772
|
list_add ( &static_ipoib_qp.recv.list,
|
753
|
773
|
&static_ipoib_recv_cq.work_queues );
|
754
|
774
|
|
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 ) {
|
|
775
|
+ struct arbelprm_query_dev_lim dev_lim;
|
|
776
|
+ memset ( &dev_lim, 0xaa, sizeof ( dev_lim ) );
|
|
777
|
+ if ( ( rc = arbel_cmd_query_dev_lim ( &static_arbel,
|
|
778
|
+ &dev_lim ) ) != 0 ) {
|
760
|
779
|
DBG ( "QUERY_DEV_LIM failed: %s\n", strerror ( rc ) );
|
761
|
780
|
}
|
762
|
781
|
DBG ( "Device limits:\n ");
|
763
|
|
- DBG_HD ( &buf[0], sizeof ( buf ) );
|
|
782
|
+ DBG_HD ( &dev_lim, sizeof ( dev_lim ) );
|
764
|
783
|
|
765
|
784
|
/* Register network device */
|
766
|
785
|
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|