|
@@ -2226,7 +2226,7 @@ static int hermon_start_firmware ( struct hermon *hermon ) {
|
2226
|
2226
|
MLX_GET ( &fw, fw_rev_subminor ) );
|
2227
|
2227
|
fw_pages = MLX_GET ( &fw, fw_pages );
|
2228
|
2228
|
DBGC ( hermon, "Hermon %p requires %d pages (%d kB) for firmware\n",
|
2229
|
|
- hermon, fw_pages, ( fw_pages * ( HERMON_PAGE_SIZE / 1024 ) ) );
|
|
2229
|
+ hermon, fw_pages, ( fw_pages * 4 ) );
|
2230
|
2230
|
|
2231
|
2231
|
/* Allocate firmware pages and map firmware area */
|
2232
|
2232
|
fw_size = ( fw_pages * HERMON_PAGE_SIZE );
|
|
@@ -2341,43 +2341,19 @@ static int hermon_get_cap ( struct hermon *hermon ) {
|
2341
|
2341
|
}
|
2342
|
2342
|
|
2343
|
2343
|
/**
|
2344
|
|
- * Get ICM usage
|
|
2344
|
+ * Align ICM table
|
2345
|
2345
|
*
|
2346
|
|
- * @v log_num_entries Log2 of the number of entries
|
2347
|
|
- * @v entry_size Entry size
|
2348
|
|
- * @ret usage Usage size in ICM
|
|
2346
|
+ * @v icm_offset Current ICM offset
|
|
2347
|
+ * @v len ICM table length
|
|
2348
|
+ * @ret icm_offset ICM offset
|
2349
|
2349
|
*/
|
2350
|
|
-static size_t icm_usage ( unsigned int log_num_entries, size_t entry_size ) {
|
2351
|
|
- size_t usage;
|
|
2350
|
+static uint64_t icm_align ( uint64_t icm_offset, size_t len ) {
|
2352
|
2351
|
|
2353
|
|
- usage = ( ( 1 << log_num_entries ) * entry_size );
|
2354
|
|
- usage = ( ( usage + HERMON_PAGE_SIZE - 1 ) &
|
2355
|
|
- ~( HERMON_PAGE_SIZE - 1 ) );
|
2356
|
|
- return usage;
|
|
2352
|
+ /* Round up to a multiple of the table size */
|
|
2353
|
+ assert ( len == ( 1UL << ( fls ( len ) - 1 ) ) );
|
|
2354
|
+ return ( ( icm_offset + len - 1 ) & ~( ( ( uint64_t ) len ) - 1 ) );
|
2357
|
2355
|
}
|
2358
|
2356
|
|
2359
|
|
-/**
|
2360
|
|
- * Align ICM
|
2361
|
|
- *
|
2362
|
|
- * @v member_size Member size
|
2363
|
|
- * @v cur_icm_offset Current ICM offset
|
2364
|
|
- * @ret align_offset Align to offset
|
2365
|
|
- */
|
2366
|
|
-static size_t icm_align ( u32 member_size,
|
2367
|
|
- u64 cur_icm_offset ) {
|
2368
|
|
- size_t align_offset = 0;
|
2369
|
|
-
|
2370
|
|
- member_size = member_size & 0xfffff000;
|
2371
|
|
- if ( member_size ) {
|
2372
|
|
- while ( ( cur_icm_offset + align_offset ) % member_size ) {
|
2373
|
|
- align_offset += HERMON_PAGE_SIZE;
|
2374
|
|
- }
|
2375
|
|
- }
|
2376
|
|
-
|
2377
|
|
- return align_offset;
|
2378
|
|
-}
|
2379
|
|
-
|
2380
|
|
-
|
2381
|
2357
|
/**
|
2382
|
2358
|
* Allocate ICM
|
2383
|
2359
|
*
|
|
@@ -2390,12 +2366,11 @@ static int hermon_alloc_icm ( struct hermon *hermon,
|
2390
|
2366
|
struct hermonprm_scalar_parameter icm_size;
|
2391
|
2367
|
struct hermonprm_scalar_parameter icm_aux_size;
|
2392
|
2368
|
uint64_t icm_offset = 0;
|
2393
|
|
- u32 icm_member_size = 0;
|
2394
|
2369
|
unsigned int log_num_qps, log_num_srqs, log_num_cqs, log_num_eqs;
|
2395
|
|
- unsigned int log_num_mtts, log_num_mpts;
|
|
2370
|
+ unsigned int log_num_mtts, log_num_mpts, log_num_mcs;
|
2396
|
2371
|
size_t cmpt_max_len;
|
2397
|
|
- size_t qp_cmpt_len, srq_cmpt_len, cq_cmpt_len, eq_cmpt_len;
|
2398
|
2372
|
size_t icm_len, icm_aux_len;
|
|
2373
|
+ size_t len;
|
2399
|
2374
|
physaddr_t icm_phys;
|
2400
|
2375
|
int i;
|
2401
|
2376
|
int rc;
|
|
@@ -2412,32 +2387,38 @@ static int hermon_alloc_icm ( struct hermon *hermon,
|
2412
|
2387
|
log_num_cqs = fls ( hermon->cap.reserved_cqs + HERMON_MAX_CQS - 1 );
|
2413
|
2388
|
log_num_eqs = fls ( hermon->cap.reserved_eqs + HERMON_MAX_EQS - 1 );
|
2414
|
2389
|
log_num_mtts = fls ( hermon->cap.reserved_mtts + HERMON_MAX_MTTS - 1 );
|
|
2390
|
+ log_num_mpts = fls ( hermon->cap.reserved_mrws + 1 - 1 );
|
|
2391
|
+ log_num_mcs = HERMON_LOG_MULTICAST_HASH_SIZE;
|
2415
|
2392
|
|
2416
|
2393
|
/* ICM starts with the cMPT tables, which are sparse */
|
2417
|
2394
|
cmpt_max_len = ( HERMON_CMPT_MAX_ENTRIES *
|
2418
|
2395
|
( ( uint64_t ) hermon->cap.cmpt_entry_size ) );
|
2419
|
|
- qp_cmpt_len = icm_usage ( log_num_qps, hermon->cap.cmpt_entry_size );
|
|
2396
|
+ len = ( ( ( ( 1 << log_num_qps ) * hermon->cap.cmpt_entry_size ) +
|
|
2397
|
+ HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
|
2420
|
2398
|
hermon->icm_map[HERMON_ICM_QP_CMPT].offset = icm_offset;
|
2421
|
|
- hermon->icm_map[HERMON_ICM_QP_CMPT].len = qp_cmpt_len;
|
|
2399
|
+ hermon->icm_map[HERMON_ICM_QP_CMPT].len = len;
|
2422
|
2400
|
icm_offset += cmpt_max_len;
|
2423
|
|
- srq_cmpt_len = icm_usage ( log_num_srqs, hermon->cap.cmpt_entry_size );
|
|
2401
|
+ len = ( ( ( ( 1 << log_num_srqs ) * hermon->cap.cmpt_entry_size ) +
|
|
2402
|
+ HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
|
2424
|
2403
|
hermon->icm_map[HERMON_ICM_SRQ_CMPT].offset = icm_offset;
|
2425
|
|
- hermon->icm_map[HERMON_ICM_SRQ_CMPT].len = srq_cmpt_len;
|
|
2404
|
+ hermon->icm_map[HERMON_ICM_SRQ_CMPT].len = len;
|
2426
|
2405
|
icm_offset += cmpt_max_len;
|
2427
|
|
- cq_cmpt_len = icm_usage ( log_num_cqs, hermon->cap.cmpt_entry_size );
|
|
2406
|
+ len = ( ( ( ( 1 << log_num_cqs ) * hermon->cap.cmpt_entry_size ) +
|
|
2407
|
+ HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
|
2428
|
2408
|
hermon->icm_map[HERMON_ICM_CQ_CMPT].offset = icm_offset;
|
2429
|
|
- hermon->icm_map[HERMON_ICM_CQ_CMPT].len = cq_cmpt_len;
|
|
2409
|
+ hermon->icm_map[HERMON_ICM_CQ_CMPT].len = len;
|
2430
|
2410
|
icm_offset += cmpt_max_len;
|
2431
|
|
- eq_cmpt_len = icm_usage ( log_num_eqs, hermon->cap.cmpt_entry_size );
|
|
2411
|
+ len = ( ( ( ( 1 << log_num_eqs ) * hermon->cap.cmpt_entry_size ) +
|
|
2412
|
+ HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
|
2432
|
2413
|
hermon->icm_map[HERMON_ICM_EQ_CMPT].offset = icm_offset;
|
2433
|
|
- hermon->icm_map[HERMON_ICM_EQ_CMPT].len = eq_cmpt_len;
|
|
2414
|
+ hermon->icm_map[HERMON_ICM_EQ_CMPT].len = len;
|
2434
|
2415
|
icm_offset += cmpt_max_len;
|
2435
|
2416
|
|
2436
|
2417
|
hermon->icm_map[HERMON_ICM_OTHER].offset = icm_offset;
|
2437
|
2418
|
|
2438
|
2419
|
/* Queue pair contexts */
|
2439
|
|
- icm_member_size = icm_usage ( log_num_qps, hermon->cap.qpc_entry_size );
|
2440
|
|
- icm_offset += icm_align ( icm_member_size, icm_offset );
|
|
2420
|
+ len = ( ( 1 << log_num_qps ) * hermon->cap.qpc_entry_size );
|
|
2421
|
+ icm_offset = icm_align ( icm_offset, len );
|
2441
|
2422
|
MLX_FILL_1 ( init_hca, 12,
|
2442
|
2423
|
qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_h,
|
2443
|
2424
|
( icm_offset >> 32 ) );
|
|
@@ -2446,38 +2427,42 @@ static int hermon_alloc_icm ( struct hermon *hermon,
|
2446
|
2427
|
( icm_offset >> 5 ),
|
2447
|
2428
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_qp,
|
2448
|
2429
|
log_num_qps );
|
2449
|
|
- DBGC ( hermon, "Hermon %p ICM QPC base = %llx\n", hermon, icm_offset );
|
2450
|
|
- icm_offset += icm_member_size;
|
|
2430
|
+ DBGC ( hermon, "Hermon %p ICM QPC is %d x %#zx at [%08llx,%08llx)\n",
|
|
2431
|
+ hermon, ( 1 << log_num_qps ), hermon->cap.qpc_entry_size,
|
|
2432
|
+ icm_offset, ( icm_offset + len ) );
|
|
2433
|
+ icm_offset += len;
|
2451
|
2434
|
|
2452
|
2435
|
/* Extended alternate path contexts */
|
2453
|
|
- icm_member_size = icm_usage ( log_num_qps,
|
2454
|
|
- hermon->cap.altc_entry_size );
|
2455
|
|
- icm_offset += icm_align ( icm_member_size, icm_offset );
|
|
2436
|
+ len = ( ( 1 << log_num_qps ) * hermon->cap.altc_entry_size );
|
|
2437
|
+ icm_offset = icm_align ( icm_offset, len );
|
2456
|
2438
|
MLX_FILL_1 ( init_hca, 24,
|
2457
|
2439
|
qpc_eec_cqc_eqc_rdb_parameters.altc_base_addr_h,
|
2458
|
2440
|
( icm_offset >> 32 ) );
|
2459
|
2441
|
MLX_FILL_1 ( init_hca, 25,
|
2460
|
2442
|
qpc_eec_cqc_eqc_rdb_parameters.altc_base_addr_l,
|
2461
|
2443
|
icm_offset );
|
2462
|
|
- DBGC ( hermon, "Hermon %p ICM ALTC base = %llx\n", hermon, icm_offset);
|
2463
|
|
- icm_offset += icm_member_size;
|
|
2444
|
+ DBGC ( hermon, "Hermon %p ICM ALTC is %d x %#zx at [%08llx,%08llx)\n",
|
|
2445
|
+ hermon, ( 1 << log_num_qps ), hermon->cap.altc_entry_size,
|
|
2446
|
+ icm_offset, ( icm_offset + len ) );
|
|
2447
|
+ icm_offset += len;
|
2464
|
2448
|
|
2465
|
2449
|
/* Extended auxiliary contexts */
|
2466
|
|
- icm_member_size = icm_usage ( log_num_qps,
|
2467
|
|
- hermon->cap.auxc_entry_size );
|
2468
|
|
- icm_offset += icm_align ( icm_member_size, icm_offset );
|
|
2450
|
+ len = ( ( 1 << log_num_qps ) * hermon->cap.auxc_entry_size );
|
|
2451
|
+ icm_offset = icm_align ( icm_offset, len );
|
2469
|
2452
|
MLX_FILL_1 ( init_hca, 28,
|
2470
|
2453
|
qpc_eec_cqc_eqc_rdb_parameters.auxc_base_addr_h,
|
2471
|
2454
|
( icm_offset >> 32 ) );
|
2472
|
2455
|
MLX_FILL_1 ( init_hca, 29,
|
2473
|
2456
|
qpc_eec_cqc_eqc_rdb_parameters.auxc_base_addr_l,
|
2474
|
2457
|
icm_offset );
|
2475
|
|
- DBGC ( hermon, "Hermon %p ICM AUXC base = %llx\n", hermon, icm_offset);
|
2476
|
|
- icm_offset += icm_member_size;
|
|
2458
|
+ DBGC ( hermon, "Hermon %p ICM AUXC is %d x %#zx at [%08llx,%08llx)\n",
|
|
2459
|
+ hermon, ( 1 << log_num_qps ), hermon->cap.auxc_entry_size,
|
|
2460
|
+ icm_offset, ( icm_offset + len ) );
|
|
2461
|
+ icm_offset += len;
|
|
2462
|
+
|
2477
|
2463
|
/* Shared receive queue contexts */
|
2478
|
|
- icm_member_size = icm_usage ( log_num_srqs,
|
2479
|
|
- hermon->cap.srqc_entry_size );
|
2480
|
|
- icm_offset += icm_align ( icm_member_size, icm_offset );
|
|
2464
|
+ len = ( ( 1 << log_num_srqs ) * hermon->cap.srqc_entry_size );
|
|
2465
|
+ icm_offset = icm_align ( icm_offset, len );
|
2481
|
2466
|
MLX_FILL_1 ( init_hca, 18,
|
2482
|
2467
|
qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_h,
|
2483
|
2468
|
( icm_offset >> 32 ) );
|
|
@@ -2486,12 +2471,14 @@ static int hermon_alloc_icm ( struct hermon *hermon,
|
2486
|
2471
|
( icm_offset >> 5 ),
|
2487
|
2472
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq,
|
2488
|
2473
|
log_num_srqs );
|
2489
|
|
- DBGC ( hermon, "Hermon %p ICM SRQC base = %llx\n", hermon, icm_offset);
|
2490
|
|
- icm_offset += icm_member_size;
|
|
2474
|
+ DBGC ( hermon, "Hermon %p ICM SRQC is %d x %#zx at [%08llx,%08llx)\n",
|
|
2475
|
+ hermon, ( 1 << log_num_srqs ), hermon->cap.srqc_entry_size,
|
|
2476
|
+ icm_offset, ( icm_offset + len ) );
|
|
2477
|
+ icm_offset += len;
|
2491
|
2478
|
|
2492
|
2479
|
/* Completion queue contexts */
|
2493
|
|
- icm_member_size = icm_usage ( log_num_cqs, hermon->cap.cqc_entry_size );
|
2494
|
|
- icm_offset += icm_align ( icm_member_size, icm_offset );
|
|
2480
|
+ len = ( ( 1 << log_num_cqs ) * hermon->cap.cqc_entry_size );
|
|
2481
|
+ icm_offset = icm_align ( icm_offset, len );
|
2495
|
2482
|
MLX_FILL_1 ( init_hca, 20,
|
2496
|
2483
|
qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_h,
|
2497
|
2484
|
( icm_offset >> 32 ) );
|
|
@@ -2500,12 +2487,14 @@ static int hermon_alloc_icm ( struct hermon *hermon,
|
2500
|
2487
|
( icm_offset >> 5 ),
|
2501
|
2488
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_cq,
|
2502
|
2489
|
log_num_cqs );
|
2503
|
|
- DBGC ( hermon, "Hermon %p ICM CQC base = %llx\n", hermon, icm_offset );
|
2504
|
|
- icm_offset += icm_member_size;
|
|
2490
|
+ DBGC ( hermon, "Hermon %p ICM CQC is %d x %#zx at [%08llx,%08llx)\n",
|
|
2491
|
+ hermon, ( 1 << log_num_cqs ), hermon->cap.cqc_entry_size,
|
|
2492
|
+ icm_offset, ( icm_offset + len ) );
|
|
2493
|
+ icm_offset += len;
|
2505
|
2494
|
|
2506
|
2495
|
/* Event queue contexts */
|
2507
|
|
- icm_member_size = icm_usage ( log_num_eqs, hermon->cap.eqc_entry_size );
|
2508
|
|
- icm_offset += icm_align ( icm_member_size, icm_offset );
|
|
2496
|
+ len = ( ( 1 << log_num_eqs ) * hermon->cap.eqc_entry_size );
|
|
2497
|
+ icm_offset = icm_align ( icm_offset, len );
|
2509
|
2498
|
MLX_FILL_1 ( init_hca, 32,
|
2510
|
2499
|
qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_h,
|
2511
|
2500
|
( icm_offset >> 32 ) );
|
|
@@ -2514,39 +2503,40 @@ static int hermon_alloc_icm ( struct hermon *hermon,
|
2514
|
2503
|
( icm_offset >> 5 ),
|
2515
|
2504
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_eq,
|
2516
|
2505
|
log_num_eqs );
|
2517
|
|
- DBGC ( hermon, "Hermon %p ICM EQC base = %llx\n", hermon, icm_offset );
|
2518
|
|
- icm_offset += icm_member_size;
|
|
2506
|
+ DBGC ( hermon, "Hermon %p ICM EQC is %d x %#zx at [%08llx,%08llx)\n",
|
|
2507
|
+ hermon, ( 1 << log_num_eqs ), hermon->cap.eqc_entry_size,
|
|
2508
|
+ icm_offset, ( icm_offset + len ) );
|
|
2509
|
+ icm_offset += len;
|
2519
|
2510
|
|
2520
|
2511
|
/* Memory translation table */
|
2521
|
|
- icm_member_size = icm_usage ( log_num_mtts,
|
2522
|
|
- hermon->cap.mtt_entry_size );
|
2523
|
|
- icm_offset += icm_align ( icm_member_size, icm_offset );
|
|
2512
|
+ len = ( ( 1 << log_num_mtts ) * hermon->cap.mtt_entry_size );
|
|
2513
|
+ icm_offset = icm_align ( icm_offset, len );
|
2524
|
2514
|
MLX_FILL_1 ( init_hca, 64,
|
2525
|
2515
|
tpt_parameters.mtt_base_addr_h, ( icm_offset >> 32 ) );
|
2526
|
2516
|
MLX_FILL_1 ( init_hca, 65,
|
2527
|
2517
|
tpt_parameters.mtt_base_addr_l, icm_offset );
|
2528
|
|
- DBGC ( hermon, "Hermon %p ICM MTT base = %llx\n", hermon, icm_offset );
|
2529
|
|
- icm_offset += icm_member_size;
|
|
2518
|
+ DBGC ( hermon, "Hermon %p ICM MTT is %d x %#zx at [%08llx,%08llx)\n",
|
|
2519
|
+ hermon, ( 1 << log_num_mtts ), hermon->cap.mtt_entry_size,
|
|
2520
|
+ icm_offset, ( icm_offset + len ) );
|
|
2521
|
+ icm_offset += len;
|
2530
|
2522
|
|
2531
|
2523
|
/* Memory protection table */
|
2532
|
|
- log_num_mpts = fls ( hermon->cap.reserved_mrws + 1 - 1 );
|
2533
|
|
- icm_member_size = icm_usage ( log_num_mpts,
|
2534
|
|
- hermon->cap.dmpt_entry_size );
|
2535
|
|
- icm_offset += icm_align ( icm_member_size, icm_offset );
|
|
2524
|
+ len = ( ( 1 << log_num_mpts ) * hermon->cap.dmpt_entry_size );
|
|
2525
|
+ icm_offset = icm_align ( icm_offset, len );
|
2536
|
2526
|
MLX_FILL_1 ( init_hca, 60,
|
2537
|
2527
|
tpt_parameters.dmpt_base_adr_h, ( icm_offset >> 32 ) );
|
2538
|
2528
|
MLX_FILL_1 ( init_hca, 61,
|
2539
|
2529
|
tpt_parameters.dmpt_base_adr_l, icm_offset );
|
2540
|
2530
|
MLX_FILL_1 ( init_hca, 62,
|
2541
|
2531
|
tpt_parameters.log_dmpt_sz, log_num_mpts );
|
2542
|
|
- DBGC ( hermon, "Hermon %p ICM DMPT base = %llx\n", hermon, icm_offset);
|
2543
|
|
- icm_offset += icm_usage ( log_num_mpts,
|
2544
|
|
- hermon->cap.dmpt_entry_size );
|
|
2532
|
+ DBGC ( hermon, "Hermon %p ICM DMPT is %d x %#zx at [%08llx,%08llx)\n",
|
|
2533
|
+ hermon, ( 1 << log_num_mpts ), hermon->cap.dmpt_entry_size,
|
|
2534
|
+ icm_offset, ( icm_offset + len ) );
|
|
2535
|
+ icm_offset += len;
|
2545
|
2536
|
|
2546
|
2537
|
/* Multicast table */
|
2547
|
|
- icm_member_size = ( ( 128 * sizeof ( struct hermonprm_mcg_entry ) +
|
2548
|
|
- HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
|
2549
|
|
- icm_offset += icm_align ( icm_member_size, icm_offset );
|
|
2538
|
+ len = ( ( 1 << log_num_mcs ) * sizeof ( struct hermonprm_mcg_entry ) );
|
|
2539
|
+ icm_offset = icm_align ( icm_offset, len );
|
2550
|
2540
|
MLX_FILL_1 ( init_hca, 48,
|
2551
|
2541
|
multicast_parameters.mc_base_addr_h,
|
2552
|
2542
|
( icm_offset >> 32 ) );
|
|
@@ -2556,11 +2546,14 @@ static int hermon_alloc_icm ( struct hermon *hermon,
|
2556
|
2546
|
multicast_parameters.log_mc_table_entry_sz,
|
2557
|
2547
|
fls ( sizeof ( struct hermonprm_mcg_entry ) - 1 ) );
|
2558
|
2548
|
MLX_FILL_1 ( init_hca, 53,
|
2559
|
|
- multicast_parameters.log_mc_table_hash_sz, 7 );
|
|
2549
|
+ multicast_parameters.log_mc_table_hash_sz, log_num_mcs );
|
2560
|
2550
|
MLX_FILL_1 ( init_hca, 54,
|
2561
|
|
- multicast_parameters.log_mc_table_sz, 7 );
|
2562
|
|
- DBGC ( hermon, "Hermon %p ICM MC base = %llx\n", hermon, icm_offset );
|
2563
|
|
- icm_offset += icm_member_size;
|
|
2551
|
+ multicast_parameters.log_mc_table_sz, log_num_mcs );
|
|
2552
|
+ DBGC ( hermon, "Hermon %p ICM MC is %d x %#zx at [%08llx,%08llx)\n",
|
|
2553
|
+ hermon, ( 1 << log_num_mcs ),
|
|
2554
|
+ sizeof ( struct hermonprm_mcg_entry ),
|
|
2555
|
+ icm_offset, ( icm_offset + len ) );
|
|
2556
|
+ icm_offset += len;
|
2564
|
2557
|
|
2565
|
2558
|
|
2566
|
2559
|
hermon->icm_map[HERMON_ICM_OTHER].len =
|