|
@@ -1981,7 +1981,7 @@ static int arbel_start_firmware ( struct arbel *arbel ) {
|
1981
|
1981
|
arbel_cmd_enable_lam ( arbel, &lam );
|
1982
|
1982
|
|
1983
|
1983
|
/* Allocate firmware pages and map firmware area */
|
1984
|
|
- fw_size = ( fw_pages * 4096 );
|
|
1984
|
+ fw_size = ( fw_pages * ARBEL_PAGE_SIZE );
|
1985
|
1985
|
arbel->firmware_area = umalloc ( fw_size * 2 );
|
1986
|
1986
|
if ( ! arbel->firmware_area ) {
|
1987
|
1987
|
rc = -ENOMEM;
|
|
@@ -2092,18 +2092,17 @@ static int arbel_get_limits ( struct arbel *arbel ) {
|
2092
|
2092
|
}
|
2093
|
2093
|
|
2094
|
2094
|
/**
|
2095
|
|
- * Get ICM usage
|
|
2095
|
+ * Align ICM table
|
2096
|
2096
|
*
|
2097
|
|
- * @v log_num_entries Log2 of the number of entries
|
2098
|
|
- * @v entry_size Entry size
|
2099
|
|
- * @ret usage Usage size in ICM
|
|
2097
|
+ * @v icm_offset Current ICM offset
|
|
2098
|
+ * @v len ICM table length
|
|
2099
|
+ * @ret icm_offset ICM offset
|
2100
|
2100
|
*/
|
2101
|
|
-static size_t icm_usage ( unsigned int log_num_entries, size_t entry_size ) {
|
2102
|
|
- size_t usage;
|
|
2101
|
+static size_t icm_align ( size_t icm_offset, size_t len ) {
|
2103
|
2102
|
|
2104
|
|
- usage = ( ( 1 << log_num_entries ) * entry_size );
|
2105
|
|
- usage = ( ( usage + 4095 ) & ~4095 );
|
2106
|
|
- return usage;
|
|
2103
|
+ /* Round up to a multiple of the table size */
|
|
2104
|
+ assert ( len == ( 1UL << ( fls ( len ) - 1 ) ) );
|
|
2105
|
+ return ( ( icm_offset + len - 1 ) & ~( len - 1 ) );
|
2107
|
2106
|
}
|
2108
|
2107
|
|
2109
|
2108
|
/**
|
|
@@ -2123,6 +2122,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
|
2123
|
2122
|
size_t icm_offset = 0;
|
2124
|
2123
|
unsigned int log_num_qps, log_num_srqs, log_num_ees, log_num_cqs;
|
2125
|
2124
|
unsigned int log_num_mtts, log_num_mpts, log_num_rdbs, log_num_eqs;
|
|
2125
|
+ unsigned int log_num_mcs;
|
|
2126
|
+ size_t len;
|
2126
|
2127
|
int rc;
|
2127
|
2128
|
|
2128
|
2129
|
icm_offset = ( ( arbel->limits.reserved_uars + 1 ) << 12 );
|
|
@@ -2130,108 +2131,143 @@ static int arbel_alloc_icm ( struct arbel *arbel,
|
2130
|
2131
|
/* Queue pair contexts */
|
2131
|
2132
|
log_num_qps = fls ( arbel->limits.reserved_qps +
|
2132
|
2133
|
ARBEL_RSVD_SPECIAL_QPS + ARBEL_MAX_QPS - 1 );
|
|
2134
|
+ len = ( ( 1 << log_num_qps ) * arbel->limits.qpc_entry_size );
|
|
2135
|
+ icm_offset = icm_align ( icm_offset, len );
|
2133
|
2136
|
MLX_FILL_2 ( init_hca, 13,
|
2134
|
2137
|
qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_l,
|
2135
|
2138
|
( icm_offset >> 7 ),
|
2136
|
2139
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_qp,
|
2137
|
2140
|
log_num_qps );
|
2138
|
|
- DBGC ( arbel, "Arbel %p ICM QPC base = %zx\n", arbel, icm_offset );
|
2139
|
|
- icm_offset += icm_usage ( log_num_qps, arbel->limits.qpc_entry_size );
|
|
2141
|
+ DBGC ( arbel, "Arbel %p ICM QPC at [%zx,%zx)\n",
|
|
2142
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2143
|
+ icm_offset += len;
|
2140
|
2144
|
|
2141
|
2145
|
/* Extended queue pair contexts */
|
|
2146
|
+ len = ( ( 1 << log_num_qps ) * arbel->limits.eqpc_entry_size );
|
|
2147
|
+ icm_offset = icm_align ( icm_offset, len );
|
2142
|
2148
|
MLX_FILL_1 ( init_hca, 25,
|
2143
|
2149
|
qpc_eec_cqc_eqc_rdb_parameters.eqpc_base_addr_l,
|
2144
|
2150
|
icm_offset );
|
2145
|
|
- DBGC ( arbel, "Arbel %p ICM EQPC base = %zx\n", arbel, icm_offset );
|
2146
|
|
- // icm_offset += icm_usage ( log_num_qps, arbel->limits.eqpc_entry_size );
|
2147
|
|
- icm_offset += icm_usage ( log_num_qps, arbel->limits.qpc_entry_size );
|
|
2151
|
+ DBGC ( arbel, "Arbel %p ICM EQPC at [%zx,%zx)\n",
|
|
2152
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2153
|
+ icm_offset += len;
|
2148
|
2154
|
|
2149
|
2155
|
/* Shared receive queue contexts */
|
2150
|
2156
|
log_num_srqs = fls ( arbel->limits.reserved_srqs - 1 );
|
|
2157
|
+ len = ( ( 1 << log_num_srqs ) * arbel->limits.srqc_entry_size );
|
|
2158
|
+ icm_offset = icm_align ( icm_offset, len );
|
2151
|
2159
|
MLX_FILL_2 ( init_hca, 19,
|
2152
|
2160
|
qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_l,
|
2153
|
2161
|
( icm_offset >> 5 ),
|
2154
|
2162
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq,
|
2155
|
2163
|
log_num_srqs );
|
2156
|
|
- DBGC ( arbel, "Arbel %p ICM SRQC base = %zx\n", arbel, icm_offset );
|
2157
|
|
- icm_offset += icm_usage ( log_num_srqs, arbel->limits.srqc_entry_size );
|
|
2164
|
+ DBGC ( arbel, "Arbel %p ICM SRQC at [%zx,%zx)\n",
|
|
2165
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2166
|
+ icm_offset += len;
|
2158
|
2167
|
|
2159
|
2168
|
/* End-to-end contexts */
|
2160
|
2169
|
log_num_ees = fls ( arbel->limits.reserved_ees - 1 );
|
|
2170
|
+ len = ( ( 1 << log_num_ees ) * arbel->limits.eec_entry_size );
|
|
2171
|
+ icm_offset = icm_align ( icm_offset, len );
|
2161
|
2172
|
MLX_FILL_2 ( init_hca, 17,
|
2162
|
2173
|
qpc_eec_cqc_eqc_rdb_parameters.eec_base_addr_l,
|
2163
|
2174
|
( icm_offset >> 7 ),
|
2164
|
2175
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_ee,
|
2165
|
2176
|
log_num_ees );
|
2166
|
|
- DBGC ( arbel, "Arbel %p ICM EEC base = %zx\n", arbel, icm_offset );
|
2167
|
|
- icm_offset += icm_usage ( log_num_ees, arbel->limits.eec_entry_size );
|
|
2177
|
+ DBGC ( arbel, "Arbel %p ICM EEC at [%zx,%zx)\n",
|
|
2178
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2179
|
+ icm_offset += len;
|
2168
|
2180
|
|
2169
|
2181
|
/* Extended end-to-end contexts */
|
|
2182
|
+ len = ( ( 1 << log_num_ees ) * arbel->limits.eeec_entry_size );
|
|
2183
|
+ icm_offset = icm_align ( icm_offset, len );
|
2170
|
2184
|
MLX_FILL_1 ( init_hca, 29,
|
2171
|
2185
|
qpc_eec_cqc_eqc_rdb_parameters.eeec_base_addr_l,
|
2172
|
2186
|
icm_offset );
|
2173
|
|
- DBGC ( arbel, "Arbel %p ICM EEEC base = %zx\n", arbel, icm_offset );
|
2174
|
|
- icm_offset += icm_usage ( log_num_ees, arbel->limits.eeec_entry_size );
|
|
2187
|
+ DBGC ( arbel, "Arbel %p ICM EEEC at [%zx,%zx)\n",
|
|
2188
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2189
|
+ icm_offset += len;
|
2175
|
2190
|
|
2176
|
2191
|
/* Completion queue contexts */
|
2177
|
2192
|
log_num_cqs = fls ( arbel->limits.reserved_cqs + ARBEL_MAX_CQS - 1 );
|
|
2193
|
+ len = ( ( 1 << log_num_cqs ) * arbel->limits.cqc_entry_size );
|
|
2194
|
+ icm_offset = icm_align ( icm_offset, len );
|
2178
|
2195
|
MLX_FILL_2 ( init_hca, 21,
|
2179
|
2196
|
qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_l,
|
2180
|
2197
|
( icm_offset >> 6 ),
|
2181
|
2198
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_of_cq,
|
2182
|
2199
|
log_num_cqs );
|
2183
|
|
- DBGC ( arbel, "Arbel %p ICM CQC base = %zx\n", arbel, icm_offset );
|
2184
|
|
- icm_offset += icm_usage ( log_num_cqs, arbel->limits.cqc_entry_size );
|
|
2200
|
+ DBGC ( arbel, "Arbel %p ICM CQC at [%zx,%zx)\n",
|
|
2201
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2202
|
+ icm_offset += len;
|
2185
|
2203
|
|
2186
|
2204
|
/* Memory translation table */
|
2187
|
2205
|
log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
|
|
2206
|
+ len = ( ( 1 << log_num_mtts ) * arbel->limits.mtt_entry_size );
|
|
2207
|
+ icm_offset = icm_align ( icm_offset, len );
|
2188
|
2208
|
MLX_FILL_1 ( init_hca, 65,
|
2189
|
2209
|
tpt_parameters.mtt_base_addr_l, icm_offset );
|
2190
|
|
- DBGC ( arbel, "Arbel %p ICM MTT base = %zx\n", arbel, icm_offset );
|
2191
|
|
- icm_offset += icm_usage ( log_num_mtts, arbel->limits.mtt_entry_size );
|
|
2210
|
+ DBGC ( arbel, "Arbel %p ICM MTT at [%zx,%zx)\n",
|
|
2211
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2212
|
+ icm_offset += len;
|
2192
|
2213
|
|
2193
|
2214
|
/* Memory protection table */
|
2194
|
2215
|
log_num_mpts = fls ( arbel->limits.reserved_mrws + 1 - 1 );
|
|
2216
|
+ len = ( ( 1 << log_num_mpts ) * arbel->limits.mpt_entry_size );
|
|
2217
|
+ icm_offset = icm_align ( icm_offset, len );
|
2195
|
2218
|
MLX_FILL_1 ( init_hca, 61,
|
2196
|
2219
|
tpt_parameters.mpt_base_adr_l, icm_offset );
|
2197
|
2220
|
MLX_FILL_1 ( init_hca, 62,
|
2198
|
2221
|
tpt_parameters.log_mpt_sz, log_num_mpts );
|
2199
|
|
- DBGC ( arbel, "Arbel %p ICM MTT base = %zx\n", arbel, icm_offset );
|
2200
|
|
- icm_offset += icm_usage ( log_num_mpts, arbel->limits.mpt_entry_size );
|
|
2222
|
+ DBGC ( arbel, "Arbel %p ICM MTT at [%zx,%zx)\n",
|
|
2223
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2224
|
+ icm_offset += len;
|
2201
|
2225
|
|
2202
|
|
- /* RDMA something or other */
|
|
2226
|
+ /* Remote read data base table */
|
2203
|
2227
|
log_num_rdbs = fls ( arbel->limits.reserved_rdbs - 1 );
|
|
2228
|
+ len = ( ( 1 << log_num_rdbs ) * ARBEL_RDB_ENTRY_SIZE );
|
|
2229
|
+ icm_offset = icm_align ( icm_offset, len );
|
2204
|
2230
|
MLX_FILL_1 ( init_hca, 37,
|
2205
|
2231
|
qpc_eec_cqc_eqc_rdb_parameters.rdb_base_addr_l,
|
2206
|
2232
|
icm_offset );
|
2207
|
|
- DBGC ( arbel, "Arbel %p ICM RDB base = %zx\n", arbel, icm_offset );
|
2208
|
|
- icm_offset += icm_usage ( log_num_rdbs, 32 );
|
|
2233
|
+ DBGC ( arbel, "Arbel %p ICM RDB at [%zx,%zx)\n",
|
|
2234
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2235
|
+ icm_offset += len;
|
2209
|
2236
|
|
2210
|
2237
|
/* Event queue contexts */
|
2211
|
|
- log_num_eqs = fls ( arbel->limits.reserved_eqs + ARBEL_MAX_EQS - 1 );
|
|
2238
|
+ log_num_eqs = fls ( arbel->limits.reserved_eqs + ARBEL_MAX_EQS - 1 );
|
|
2239
|
+ len = ( ( 1 << log_num_eqs ) * arbel->limits.eqc_entry_size );
|
|
2240
|
+ icm_offset = icm_align ( icm_offset, len );
|
2212
|
2241
|
MLX_FILL_2 ( init_hca, 33,
|
2213
|
2242
|
qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_l,
|
2214
|
2243
|
( icm_offset >> 6 ),
|
2215
|
2244
|
qpc_eec_cqc_eqc_rdb_parameters.log_num_eq,
|
2216
|
2245
|
log_num_eqs );
|
2217
|
|
- DBGC ( arbel, "Arbel %p ICM EQ base = %zx\n", arbel, icm_offset );
|
2218
|
|
- icm_offset += ( ( 1 << log_num_eqs ) * arbel->limits.eqc_entry_size );
|
|
2246
|
+ DBGC ( arbel, "Arbel %p ICM EQ at [%zx,%zx)\n",
|
|
2247
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2248
|
+ icm_offset += len;
|
2219
|
2249
|
|
2220
|
2250
|
/* Multicast table */
|
|
2251
|
+ log_num_mcs = ARBEL_LOG_MULTICAST_HASH_SIZE;
|
|
2252
|
+ len = ( ( 1 << log_num_mcs ) * sizeof ( struct arbelprm_mgm_entry ) );
|
|
2253
|
+ icm_offset = icm_align ( icm_offset, len );
|
2221
|
2254
|
MLX_FILL_1 ( init_hca, 49,
|
2222
|
2255
|
multicast_parameters.mc_base_addr_l, icm_offset );
|
2223
|
2256
|
MLX_FILL_1 ( init_hca, 52,
|
2224
|
2257
|
multicast_parameters.log_mc_table_entry_sz,
|
2225
|
2258
|
fls ( sizeof ( struct arbelprm_mgm_entry ) - 1 ) );
|
2226
|
2259
|
MLX_FILL_1 ( init_hca, 53,
|
2227
|
|
- multicast_parameters.mc_table_hash_sz, 8 );
|
|
2260
|
+ multicast_parameters.mc_table_hash_sz,
|
|
2261
|
+ ( 1 << log_num_mcs ) );
|
2228
|
2262
|
MLX_FILL_1 ( init_hca, 54,
|
2229
|
|
- multicast_parameters.log_mc_table_sz, 3 );
|
2230
|
|
- DBGC ( arbel, "Arbel %p ICM MC base = %zx\n", arbel, icm_offset );
|
2231
|
|
- icm_offset += ( 8 * sizeof ( struct arbelprm_mgm_entry ) );
|
|
2263
|
+ multicast_parameters.log_mc_table_sz,
|
|
2264
|
+ log_num_mcs /* Only one entry per hash */ );
|
|
2265
|
+ DBGC ( arbel, "Arbel %p ICM MC at [%zx,%zx)\n",
|
|
2266
|
+ arbel, icm_offset, ( icm_offset + len ) );
|
|
2267
|
+ icm_offset += len;
|
2232
|
2268
|
|
2233
|
|
- arbel->icm_len = icm_offset;
|
2234
|
|
- arbel->icm_len = ( ( arbel->icm_len + 4095 ) & ~4095 );
|
|
2269
|
+ /* Round up to a whole number of pages */
|
|
2270
|
+ arbel->icm_len = icm_align ( icm_offset, ARBEL_PAGE_SIZE );
|
2235
|
2271
|
|
2236
|
2272
|
/* Get ICM auxiliary area size */
|
2237
|
2273
|
memset ( &icm_size, 0, sizeof ( icm_size ) );
|
|
@@ -2242,7 +2278,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
|
2242
|
2278
|
arbel, strerror ( rc ) );
|
2243
|
2279
|
goto err_set_icm_size;
|
2244
|
2280
|
}
|
2245
|
|
- arbel->icm_aux_len = ( MLX_GET ( &icm_aux_size, value ) * 4096 );
|
|
2281
|
+ arbel->icm_aux_len =
|
|
2282
|
+ ( MLX_GET ( &icm_aux_size, value ) * ARBEL_PAGE_SIZE );
|
2246
|
2283
|
|
2247
|
2284
|
/* Allocate ICM data and auxiliary area */
|
2248
|
2285
|
DBGC ( arbel, "Arbel %p requires %zd kB ICM and %zd kB AUX ICM\n",
|
|
@@ -2257,7 +2294,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
|
2257
|
2294
|
/* Map ICM auxiliary area */
|
2258
|
2295
|
memset ( &map_icm_aux, 0, sizeof ( map_icm_aux ) );
|
2259
|
2296
|
MLX_FILL_2 ( &map_icm_aux, 3,
|
2260
|
|
- log2size, fls ( ( arbel->icm_aux_len / 4096 ) - 1 ),
|
|
2297
|
+ log2size,
|
|
2298
|
+ fls ( ( arbel->icm_aux_len / ARBEL_PAGE_SIZE ) - 1 ),
|
2261
|
2299
|
pa_l,
|
2262
|
2300
|
( user_to_phys ( arbel->icm, arbel->icm_len ) >> 12 ) );
|
2263
|
2301
|
if ( ( rc = arbel_cmd_map_icm_aux ( arbel, &map_icm_aux ) ) != 0 ) {
|
|
@@ -2269,7 +2307,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
|
2269
|
2307
|
/* MAP ICM area */
|
2270
|
2308
|
memset ( &map_icm, 0, sizeof ( map_icm ) );
|
2271
|
2309
|
MLX_FILL_2 ( &map_icm, 3,
|
2272
|
|
- log2size, fls ( ( arbel->icm_len / 4096 ) - 1 ),
|
|
2310
|
+ log2size,
|
|
2311
|
+ fls ( ( arbel->icm_len / ARBEL_PAGE_SIZE ) - 1 ),
|
2273
|
2312
|
pa_l, ( user_to_phys ( arbel->icm, 0 ) >> 12 ) );
|
2274
|
2313
|
if ( ( rc = arbel_cmd_map_icm ( arbel, &map_icm ) ) != 0 ) {
|
2275
|
2314
|
DBGC ( arbel, "Arbel %p could not map ICM: %s\n",
|
|
@@ -2287,7 +2326,7 @@ static int arbel_alloc_icm ( struct arbel *arbel,
|
2287
|
2326
|
|
2288
|
2327
|
return 0;
|
2289
|
2328
|
|
2290
|
|
- arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / 4096 ) );
|
|
2329
|
+ arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / ARBEL_PAGE_SIZE ) );
|
2291
|
2330
|
err_map_icm:
|
2292
|
2331
|
arbel_cmd_unmap_icm_aux ( arbel );
|
2293
|
2332
|
err_map_icm_aux:
|
|
@@ -2304,7 +2343,7 @@ static int arbel_alloc_icm ( struct arbel *arbel,
|
2304
|
2343
|
* @v arbel Arbel device
|
2305
|
2344
|
*/
|
2306
|
2345
|
static void arbel_free_icm ( struct arbel *arbel ) {
|
2307
|
|
- arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / 4096 ) );
|
|
2346
|
+ arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / ARBEL_PAGE_SIZE ) );
|
2308
|
2347
|
arbel_cmd_unmap_icm_aux ( arbel );
|
2309
|
2348
|
ufree ( arbel->icm );
|
2310
|
2349
|
arbel->icm = UNULL;
|