|  | @@ -2205,6 +2205,28 @@ static size_t icm_usage ( unsigned int log_num_entries, size_t entry_size ) {
 | 
		
	
		
			
			| 2205 | 2205 |  	return usage;
 | 
		
	
		
			
			| 2206 | 2206 |  }
 | 
		
	
		
			
			| 2207 | 2207 |  
 | 
		
	
		
			
			|  | 2208 | +/**
 | 
		
	
		
			
			|  | 2209 | + * Align ICM
 | 
		
	
		
			
			|  | 2210 | + *
 | 
		
	
		
			
			|  | 2211 | + * @v member_size		Member size
 | 
		
	
		
			
			|  | 2212 | + * @v cur_icm_offset	Current ICM offset
 | 
		
	
		
			
			|  | 2213 | + * @ret align_offset	Align to offset
 | 
		
	
		
			
			|  | 2214 | + */
 | 
		
	
		
			
			|  | 2215 | +static size_t icm_align ( u32 member_size,
 | 
		
	
		
			
			|  | 2216 | +						  u64 cur_icm_offset ) {
 | 
		
	
		
			
			|  | 2217 | +	size_t	align_offset = 0;
 | 
		
	
		
			
			|  | 2218 | +
 | 
		
	
		
			
			|  | 2219 | +	member_size = member_size & 0xfffff000;
 | 
		
	
		
			
			|  | 2220 | +	if ( member_size ) {
 | 
		
	
		
			
			|  | 2221 | +		while ( ( cur_icm_offset + align_offset ) % member_size ) {
 | 
		
	
		
			
			|  | 2222 | +			align_offset += HERMON_PAGE_SIZE;
 | 
		
	
		
			
			|  | 2223 | +		}
 | 
		
	
		
			
			|  | 2224 | +	}
 | 
		
	
		
			
			|  | 2225 | +
 | 
		
	
		
			
			|  | 2226 | +	return align_offset;
 | 
		
	
		
			
			|  | 2227 | +}
 | 
		
	
		
			
			|  | 2228 | +
 | 
		
	
		
			
			|  | 2229 | +
 | 
		
	
		
			
			| 2208 | 2230 |  /**
 | 
		
	
		
			
			| 2209 | 2231 |   * Allocate ICM
 | 
		
	
		
			
			| 2210 | 2232 |   *
 | 
		
	
	
		
			
			|  | @@ -2217,6 +2239,7 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2217 | 2239 |  	struct hermonprm_scalar_parameter icm_size;
 | 
		
	
		
			
			| 2218 | 2240 |  	struct hermonprm_scalar_parameter icm_aux_size;
 | 
		
	
		
			
			| 2219 | 2241 |  	uint64_t icm_offset = 0;
 | 
		
	
		
			
			|  | 2242 | +	u32 icm_member_size = 0;
 | 
		
	
		
			
			| 2220 | 2243 |  	unsigned int log_num_qps, log_num_srqs, log_num_cqs, log_num_eqs;
 | 
		
	
		
			
			| 2221 | 2244 |  	unsigned int log_num_mtts, log_num_mpts;
 | 
		
	
		
			
			| 2222 | 2245 |  	size_t cmpt_max_len;
 | 
		
	
	
		
			
			|  | @@ -2262,6 +2285,8 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2262 | 2285 |  	hermon->icm_map[HERMON_ICM_OTHER].offset = icm_offset;
 | 
		
	
		
			
			| 2263 | 2286 |  
 | 
		
	
		
			
			| 2264 | 2287 |  	/* Queue pair contexts */
 | 
		
	
		
			
			|  | 2288 | +	icm_member_size = icm_usage ( log_num_qps, hermon->cap.qpc_entry_size );
 | 
		
	
		
			
			|  | 2289 | +	icm_offset += icm_align ( icm_member_size, icm_offset );
 | 
		
	
		
			
			| 2265 | 2290 |  	MLX_FILL_1 ( init_hca, 12,
 | 
		
	
		
			
			| 2266 | 2291 |  		     qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_h,
 | 
		
	
		
			
			| 2267 | 2292 |  		     ( icm_offset >> 32 ) );
 | 
		
	
	
		
			
			|  | @@ -2271,9 +2296,12 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2271 | 2296 |  		     qpc_eec_cqc_eqc_rdb_parameters.log_num_of_qp,
 | 
		
	
		
			
			| 2272 | 2297 |  		     log_num_qps );
 | 
		
	
		
			
			| 2273 | 2298 |  	DBGC ( hermon, "Hermon %p ICM QPC base = %llx\n", hermon, icm_offset );
 | 
		
	
		
			
			| 2274 |  | -	icm_offset += icm_usage ( log_num_qps, hermon->cap.qpc_entry_size );
 | 
		
	
		
			
			|  | 2299 | +	icm_offset += icm_member_size;
 | 
		
	
		
			
			| 2275 | 2300 |  
 | 
		
	
		
			
			| 2276 | 2301 |  	/* Extended alternate path contexts */
 | 
		
	
		
			
			|  | 2302 | +	icm_member_size = icm_usage ( log_num_qps,
 | 
		
	
		
			
			|  | 2303 | +				  hermon->cap.altc_entry_size );
 | 
		
	
		
			
			|  | 2304 | +	icm_offset += icm_align ( icm_member_size, icm_offset );
 | 
		
	
		
			
			| 2277 | 2305 |  	MLX_FILL_1 ( init_hca, 24,
 | 
		
	
		
			
			| 2278 | 2306 |  		     qpc_eec_cqc_eqc_rdb_parameters.altc_base_addr_h,
 | 
		
	
		
			
			| 2279 | 2307 |  		     ( icm_offset >> 32 ) );
 | 
		
	
	
		
			
			|  | @@ -2281,10 +2309,12 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2281 | 2309 |  		     qpc_eec_cqc_eqc_rdb_parameters.altc_base_addr_l,
 | 
		
	
		
			
			| 2282 | 2310 |  		     icm_offset );
 | 
		
	
		
			
			| 2283 | 2311 |  	DBGC ( hermon, "Hermon %p ICM ALTC base = %llx\n", hermon, icm_offset);
 | 
		
	
		
			
			| 2284 |  | -	icm_offset += icm_usage ( log_num_qps,
 | 
		
	
		
			
			| 2285 |  | -				  hermon->cap.altc_entry_size );
 | 
		
	
		
			
			|  | 2312 | +	icm_offset += icm_member_size;
 | 
		
	
		
			
			| 2286 | 2313 |  
 | 
		
	
		
			
			| 2287 | 2314 |  	/* Extended auxiliary contexts */
 | 
		
	
		
			
			|  | 2315 | +	icm_member_size = icm_usage ( log_num_qps,
 | 
		
	
		
			
			|  | 2316 | +				  hermon->cap.auxc_entry_size );
 | 
		
	
		
			
			|  | 2317 | +	icm_offset += icm_align ( icm_member_size, icm_offset );
 | 
		
	
		
			
			| 2288 | 2318 |  	MLX_FILL_1 ( init_hca, 28,
 | 
		
	
		
			
			| 2289 | 2319 |  		     qpc_eec_cqc_eqc_rdb_parameters.auxc_base_addr_h,
 | 
		
	
		
			
			| 2290 | 2320 |  		     ( icm_offset >> 32 ) );
 | 
		
	
	
		
			
			|  | @@ -2292,10 +2322,11 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2292 | 2322 |  		     qpc_eec_cqc_eqc_rdb_parameters.auxc_base_addr_l,
 | 
		
	
		
			
			| 2293 | 2323 |  		     icm_offset );
 | 
		
	
		
			
			| 2294 | 2324 |  	DBGC ( hermon, "Hermon %p ICM AUXC base = %llx\n", hermon, icm_offset);
 | 
		
	
		
			
			| 2295 |  | -	icm_offset += icm_usage ( log_num_qps,
 | 
		
	
		
			
			| 2296 |  | -				  hermon->cap.auxc_entry_size );
 | 
		
	
		
			
			| 2297 |  | -
 | 
		
	
		
			
			|  | 2325 | +	icm_offset += icm_member_size;
 | 
		
	
		
			
			| 2298 | 2326 |  	/* Shared receive queue contexts */
 | 
		
	
		
			
			|  | 2327 | +	icm_member_size = icm_usage ( log_num_srqs,
 | 
		
	
		
			
			|  | 2328 | +				  hermon->cap.srqc_entry_size );
 | 
		
	
		
			
			|  | 2329 | +	icm_offset += icm_align ( icm_member_size, icm_offset );
 | 
		
	
		
			
			| 2299 | 2330 |  	MLX_FILL_1 ( init_hca, 18,
 | 
		
	
		
			
			| 2300 | 2331 |  		     qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_h,
 | 
		
	
		
			
			| 2301 | 2332 |  		     ( icm_offset >> 32 ) );
 | 
		
	
	
		
			
			|  | @@ -2305,10 +2336,11 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2305 | 2336 |  		     qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq,
 | 
		
	
		
			
			| 2306 | 2337 |  		     log_num_srqs );
 | 
		
	
		
			
			| 2307 | 2338 |  	DBGC ( hermon, "Hermon %p ICM SRQC base = %llx\n", hermon, icm_offset);
 | 
		
	
		
			
			| 2308 |  | -	icm_offset += icm_usage ( log_num_srqs,
 | 
		
	
		
			
			| 2309 |  | -				  hermon->cap.srqc_entry_size );
 | 
		
	
		
			
			|  | 2339 | +	icm_offset += icm_member_size;
 | 
		
	
		
			
			| 2310 | 2340 |  
 | 
		
	
		
			
			| 2311 | 2341 |  	/* Completion queue contexts */
 | 
		
	
		
			
			|  | 2342 | +	icm_member_size = icm_usage ( log_num_cqs, hermon->cap.cqc_entry_size );
 | 
		
	
		
			
			|  | 2343 | +	icm_offset += icm_align ( icm_member_size, icm_offset );
 | 
		
	
		
			
			| 2312 | 2344 |  	MLX_FILL_1 ( init_hca, 20,
 | 
		
	
		
			
			| 2313 | 2345 |  		     qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_h,
 | 
		
	
		
			
			| 2314 | 2346 |  		     ( icm_offset >> 32 ) );
 | 
		
	
	
		
			
			|  | @@ -2318,9 +2350,11 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2318 | 2350 |  		     qpc_eec_cqc_eqc_rdb_parameters.log_num_of_cq,
 | 
		
	
		
			
			| 2319 | 2351 |  		     log_num_cqs );
 | 
		
	
		
			
			| 2320 | 2352 |  	DBGC ( hermon, "Hermon %p ICM CQC base = %llx\n", hermon, icm_offset );
 | 
		
	
		
			
			| 2321 |  | -	icm_offset += icm_usage ( log_num_cqs, hermon->cap.cqc_entry_size );
 | 
		
	
		
			
			|  | 2353 | +	icm_offset += icm_member_size;
 | 
		
	
		
			
			| 2322 | 2354 |  
 | 
		
	
		
			
			| 2323 | 2355 |  	/* Event queue contexts */
 | 
		
	
		
			
			|  | 2356 | +	icm_member_size = icm_usage ( log_num_eqs, hermon->cap.eqc_entry_size );
 | 
		
	
		
			
			|  | 2357 | +	icm_offset += icm_align ( icm_member_size, icm_offset );
 | 
		
	
		
			
			| 2324 | 2358 |  	MLX_FILL_1 ( init_hca, 32,
 | 
		
	
		
			
			| 2325 | 2359 |  		     qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_h,
 | 
		
	
		
			
			| 2326 | 2360 |  		     ( icm_offset >> 32 ) );
 | 
		
	
	
		
			
			|  | @@ -2330,19 +2364,24 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2330 | 2364 |  		     qpc_eec_cqc_eqc_rdb_parameters.log_num_of_eq,
 | 
		
	
		
			
			| 2331 | 2365 |  		     log_num_eqs );
 | 
		
	
		
			
			| 2332 | 2366 |  	DBGC ( hermon, "Hermon %p ICM EQC base = %llx\n", hermon, icm_offset );
 | 
		
	
		
			
			| 2333 |  | -	icm_offset += icm_usage ( log_num_eqs, hermon->cap.eqc_entry_size );
 | 
		
	
		
			
			|  | 2367 | +	icm_offset += icm_member_size;
 | 
		
	
		
			
			| 2334 | 2368 |  
 | 
		
	
		
			
			| 2335 | 2369 |  	/* Memory translation table */
 | 
		
	
		
			
			|  | 2370 | +	icm_member_size = icm_usage ( log_num_mtts,
 | 
		
	
		
			
			|  | 2371 | +				  hermon->cap.mtt_entry_size );
 | 
		
	
		
			
			|  | 2372 | +	icm_offset += icm_align ( icm_member_size, icm_offset );
 | 
		
	
		
			
			| 2336 | 2373 |  	MLX_FILL_1 ( init_hca, 64,
 | 
		
	
		
			
			| 2337 | 2374 |  		     tpt_parameters.mtt_base_addr_h, ( icm_offset >> 32 ) );
 | 
		
	
		
			
			| 2338 | 2375 |  	MLX_FILL_1 ( init_hca, 65,
 | 
		
	
		
			
			| 2339 | 2376 |  		     tpt_parameters.mtt_base_addr_l, icm_offset );
 | 
		
	
		
			
			| 2340 | 2377 |  	DBGC ( hermon, "Hermon %p ICM MTT base = %llx\n", hermon, icm_offset );
 | 
		
	
		
			
			| 2341 |  | -	icm_offset += icm_usage ( log_num_mtts,
 | 
		
	
		
			
			| 2342 |  | -				  hermon->cap.mtt_entry_size );
 | 
		
	
		
			
			|  | 2378 | +	icm_offset += icm_member_size;
 | 
		
	
		
			
			| 2343 | 2379 |  
 | 
		
	
		
			
			| 2344 | 2380 |  	/* Memory protection table */
 | 
		
	
		
			
			| 2345 | 2381 |  	log_num_mpts = fls ( hermon->cap.reserved_mrws + 1 - 1 );
 | 
		
	
		
			
			|  | 2382 | +	icm_member_size = icm_usage ( log_num_mpts,
 | 
		
	
		
			
			|  | 2383 | +				  hermon->cap.dmpt_entry_size );
 | 
		
	
		
			
			|  | 2384 | +	icm_offset += icm_align ( icm_member_size, icm_offset );
 | 
		
	
		
			
			| 2346 | 2385 |  	MLX_FILL_1 ( init_hca, 60,
 | 
		
	
		
			
			| 2347 | 2386 |  		     tpt_parameters.dmpt_base_adr_h, ( icm_offset >> 32 ) );
 | 
		
	
		
			
			| 2348 | 2387 |  	MLX_FILL_1 ( init_hca, 61,
 | 
		
	
	
		
			
			|  | @@ -2354,6 +2393,9 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2354 | 2393 |  				  hermon->cap.dmpt_entry_size );
 | 
		
	
		
			
			| 2355 | 2394 |  
 | 
		
	
		
			
			| 2356 | 2395 |  	/* Multicast table */
 | 
		
	
		
			
			|  | 2396 | +	icm_member_size = ( ( 128 * sizeof ( struct hermonprm_mcg_entry ) +
 | 
		
	
		
			
			|  | 2397 | +						 HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
 | 
		
	
		
			
			|  | 2398 | +	icm_offset += icm_align ( icm_member_size, icm_offset );
 | 
		
	
		
			
			| 2357 | 2399 |  	MLX_FILL_1 ( init_hca, 48,
 | 
		
	
		
			
			| 2358 | 2400 |  		     multicast_parameters.mc_base_addr_h,
 | 
		
	
		
			
			| 2359 | 2401 |  		     ( icm_offset >> 32 ) );
 | 
		
	
	
		
			
			|  | @@ -2363,12 +2405,12 @@ static int hermon_alloc_icm ( struct hermon *hermon,
 | 
		
	
		
			
			| 2363 | 2405 |  		     multicast_parameters.log_mc_table_entry_sz,
 | 
		
	
		
			
			| 2364 | 2406 |  		     fls ( sizeof ( struct hermonprm_mcg_entry ) - 1 ) );
 | 
		
	
		
			
			| 2365 | 2407 |  	MLX_FILL_1 ( init_hca, 53,
 | 
		
	
		
			
			| 2366 |  | -		     multicast_parameters.log_mc_table_hash_sz, 3 );
 | 
		
	
		
			
			|  | 2408 | +		     multicast_parameters.log_mc_table_hash_sz, 7 );
 | 
		
	
		
			
			| 2367 | 2409 |  	MLX_FILL_1 ( init_hca, 54,
 | 
		
	
		
			
			| 2368 |  | -		     multicast_parameters.log_mc_table_sz, 3 );
 | 
		
	
		
			
			|  | 2410 | +		     multicast_parameters.log_mc_table_sz, 7 );
 | 
		
	
		
			
			| 2369 | 2411 |  	DBGC ( hermon, "Hermon %p ICM MC base = %llx\n", hermon, icm_offset );
 | 
		
	
		
			
			| 2370 |  | -	icm_offset += ( ( 8 * sizeof ( struct hermonprm_mcg_entry ) +
 | 
		
	
		
			
			| 2371 |  | -			  HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) );
 | 
		
	
		
			
			|  | 2412 | +	icm_offset += icm_member_size;
 | 
		
	
		
			
			|  | 2413 | +
 | 
		
	
		
			
			| 2372 | 2414 |  
 | 
		
	
		
			
			| 2373 | 2415 |  	hermon->icm_map[HERMON_ICM_OTHER].len =
 | 
		
	
		
			
			| 2374 | 2416 |  		( icm_offset - hermon->icm_map[HERMON_ICM_OTHER].offset );
 |