diff options
author | Roland Dreier <rolandd@cisco.com> | 2006-02-13 15:48:12 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-03-20 13:08:12 -0500 |
commit | 8a51866f08103ba04894ce0f65eef567ddc3ed40 (patch) | |
tree | 39af79ce5995900c14610acc768850a749961ee9 /drivers | |
parent | 3fa1fa3e809dc009a080ca9f052cee2e17836c63 (diff) |
IB: Add ib_modify_qp_is_ok() library function
The in-kernel mthca driver contains a table of which attributes are
valid for each queue pair state transition. It turns out that both
other IB drivers -- ipath and ehca -- which are being prepared for
merging have copied this table, errors and all.
To forestall this code duplication, move this table and the code to
check parameters against it into a midlayer library function,
ib_modify_qp_is_ok().
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/core/verbs.c | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 8e0ba16bcbdd..ca07a2be87d3 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c | |||
@@ -245,6 +245,258 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, | |||
245 | } | 245 | } |
246 | EXPORT_SYMBOL(ib_create_qp); | 246 | EXPORT_SYMBOL(ib_create_qp); |
247 | 247 | ||
248 | static const struct { | ||
249 | int valid; | ||
250 | enum ib_qp_attr_mask req_param[IB_QPT_RAW_ETY + 1]; | ||
251 | enum ib_qp_attr_mask opt_param[IB_QPT_RAW_ETY + 1]; | ||
252 | } qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { | ||
253 | [IB_QPS_RESET] = { | ||
254 | [IB_QPS_RESET] = { .valid = 1 }, | ||
255 | [IB_QPS_ERR] = { .valid = 1 }, | ||
256 | [IB_QPS_INIT] = { | ||
257 | .valid = 1, | ||
258 | .req_param = { | ||
259 | [IB_QPT_UD] = (IB_QP_PKEY_INDEX | | ||
260 | IB_QP_PORT | | ||
261 | IB_QP_QKEY), | ||
262 | [IB_QPT_UC] = (IB_QP_PKEY_INDEX | | ||
263 | IB_QP_PORT | | ||
264 | IB_QP_ACCESS_FLAGS), | ||
265 | [IB_QPT_RC] = (IB_QP_PKEY_INDEX | | ||
266 | IB_QP_PORT | | ||
267 | IB_QP_ACCESS_FLAGS), | ||
268 | [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | | ||
269 | IB_QP_QKEY), | ||
270 | [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | | ||
271 | IB_QP_QKEY), | ||
272 | } | ||
273 | }, | ||
274 | }, | ||
275 | [IB_QPS_INIT] = { | ||
276 | [IB_QPS_RESET] = { .valid = 1 }, | ||
277 | [IB_QPS_ERR] = { .valid = 1 }, | ||
278 | [IB_QPS_INIT] = { | ||
279 | .valid = 1, | ||
280 | .opt_param = { | ||
281 | [IB_QPT_UD] = (IB_QP_PKEY_INDEX | | ||
282 | IB_QP_PORT | | ||
283 | IB_QP_QKEY), | ||
284 | [IB_QPT_UC] = (IB_QP_PKEY_INDEX | | ||
285 | IB_QP_PORT | | ||
286 | IB_QP_ACCESS_FLAGS), | ||
287 | [IB_QPT_RC] = (IB_QP_PKEY_INDEX | | ||
288 | IB_QP_PORT | | ||
289 | IB_QP_ACCESS_FLAGS), | ||
290 | [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | | ||
291 | IB_QP_QKEY), | ||
292 | [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | | ||
293 | IB_QP_QKEY), | ||
294 | } | ||
295 | }, | ||
296 | [IB_QPS_RTR] = { | ||
297 | .valid = 1, | ||
298 | .req_param = { | ||
299 | [IB_QPT_UC] = (IB_QP_AV | | ||
300 | IB_QP_PATH_MTU | | ||
301 | IB_QP_DEST_QPN | | ||
302 | IB_QP_RQ_PSN), | ||
303 | [IB_QPT_RC] = (IB_QP_AV | | ||
304 | IB_QP_PATH_MTU | | ||
305 | IB_QP_DEST_QPN | | ||
306 | IB_QP_RQ_PSN | | ||
307 | IB_QP_MAX_DEST_RD_ATOMIC | | ||
308 | IB_QP_MIN_RNR_TIMER), | ||
309 | }, | ||
310 | .opt_param = { | ||
311 | [IB_QPT_UD] = (IB_QP_PKEY_INDEX | | ||
312 | IB_QP_QKEY), | ||
313 | [IB_QPT_UC] = (IB_QP_ALT_PATH | | ||
314 | IB_QP_ACCESS_FLAGS | | ||
315 | IB_QP_PKEY_INDEX), | ||
316 | [IB_QPT_RC] = (IB_QP_ALT_PATH | | ||
317 | IB_QP_ACCESS_FLAGS | | ||
318 | IB_QP_PKEY_INDEX), | ||
319 | [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | | ||
320 | IB_QP_QKEY), | ||
321 | [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | | ||
322 | IB_QP_QKEY), | ||
323 | } | ||
324 | } | ||
325 | }, | ||
326 | [IB_QPS_RTR] = { | ||
327 | [IB_QPS_RESET] = { .valid = 1 }, | ||
328 | [IB_QPS_ERR] = { .valid = 1 }, | ||
329 | [IB_QPS_RTS] = { | ||
330 | .valid = 1, | ||
331 | .req_param = { | ||
332 | [IB_QPT_UD] = IB_QP_SQ_PSN, | ||
333 | [IB_QPT_UC] = IB_QP_SQ_PSN, | ||
334 | [IB_QPT_RC] = (IB_QP_TIMEOUT | | ||
335 | IB_QP_RETRY_CNT | | ||
336 | IB_QP_RNR_RETRY | | ||
337 | IB_QP_SQ_PSN | | ||
338 | IB_QP_MAX_QP_RD_ATOMIC), | ||
339 | [IB_QPT_SMI] = IB_QP_SQ_PSN, | ||
340 | [IB_QPT_GSI] = IB_QP_SQ_PSN, | ||
341 | }, | ||
342 | .opt_param = { | ||
343 | [IB_QPT_UD] = (IB_QP_CUR_STATE | | ||
344 | IB_QP_QKEY), | ||
345 | [IB_QPT_UC] = (IB_QP_CUR_STATE | | ||
346 | IB_QP_ALT_PATH | | ||
347 | IB_QP_ACCESS_FLAGS | | ||
348 | IB_QP_PATH_MIG_STATE), | ||
349 | [IB_QPT_RC] = (IB_QP_CUR_STATE | | ||
350 | IB_QP_ALT_PATH | | ||
351 | IB_QP_ACCESS_FLAGS | | ||
352 | IB_QP_MIN_RNR_TIMER | | ||
353 | IB_QP_PATH_MIG_STATE), | ||
354 | [IB_QPT_SMI] = (IB_QP_CUR_STATE | | ||
355 | IB_QP_QKEY), | ||
356 | [IB_QPT_GSI] = (IB_QP_CUR_STATE | | ||
357 | IB_QP_QKEY), | ||
358 | } | ||
359 | } | ||
360 | }, | ||
361 | [IB_QPS_RTS] = { | ||
362 | [IB_QPS_RESET] = { .valid = 1 }, | ||
363 | [IB_QPS_ERR] = { .valid = 1 }, | ||
364 | [IB_QPS_RTS] = { | ||
365 | .valid = 1, | ||
366 | .opt_param = { | ||
367 | [IB_QPT_UD] = (IB_QP_CUR_STATE | | ||
368 | IB_QP_QKEY), | ||
369 | [IB_QPT_UC] = (IB_QP_ACCESS_FLAGS | | ||
370 | IB_QP_ALT_PATH | | ||
371 | IB_QP_PATH_MIG_STATE), | ||
372 | [IB_QPT_RC] = (IB_QP_ACCESS_FLAGS | | ||
373 | IB_QP_ALT_PATH | | ||
374 | IB_QP_PATH_MIG_STATE | | ||
375 | IB_QP_MIN_RNR_TIMER), | ||
376 | [IB_QPT_SMI] = (IB_QP_CUR_STATE | | ||
377 | IB_QP_QKEY), | ||
378 | [IB_QPT_GSI] = (IB_QP_CUR_STATE | | ||
379 | IB_QP_QKEY), | ||
380 | } | ||
381 | }, | ||
382 | [IB_QPS_SQD] = { | ||
383 | .valid = 1, | ||
384 | .opt_param = { | ||
385 | [IB_QPT_UD] = IB_QP_EN_SQD_ASYNC_NOTIFY, | ||
386 | [IB_QPT_UC] = IB_QP_EN_SQD_ASYNC_NOTIFY, | ||
387 | [IB_QPT_RC] = IB_QP_EN_SQD_ASYNC_NOTIFY, | ||
388 | [IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY, | ||
389 | [IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY | ||
390 | } | ||
391 | }, | ||
392 | }, | ||
393 | [IB_QPS_SQD] = { | ||
394 | [IB_QPS_RESET] = { .valid = 1 }, | ||
395 | [IB_QPS_ERR] = { .valid = 1 }, | ||
396 | [IB_QPS_RTS] = { | ||
397 | .valid = 1, | ||
398 | .opt_param = { | ||
399 | [IB_QPT_UD] = (IB_QP_CUR_STATE | | ||
400 | IB_QP_QKEY), | ||
401 | [IB_QPT_UC] = (IB_QP_CUR_STATE | | ||
402 | IB_QP_ALT_PATH | | ||
403 | IB_QP_ACCESS_FLAGS | | ||
404 | IB_QP_PATH_MIG_STATE), | ||
405 | [IB_QPT_RC] = (IB_QP_CUR_STATE | | ||
406 | IB_QP_ALT_PATH | | ||
407 | IB_QP_ACCESS_FLAGS | | ||
408 | IB_QP_MIN_RNR_TIMER | | ||
409 | IB_QP_PATH_MIG_STATE), | ||
410 | [IB_QPT_SMI] = (IB_QP_CUR_STATE | | ||
411 | IB_QP_QKEY), | ||
412 | [IB_QPT_GSI] = (IB_QP_CUR_STATE | | ||
413 | IB_QP_QKEY), | ||
414 | } | ||
415 | }, | ||
416 | [IB_QPS_SQD] = { | ||
417 | .valid = 1, | ||
418 | .opt_param = { | ||
419 | [IB_QPT_UD] = (IB_QP_PKEY_INDEX | | ||
420 | IB_QP_QKEY), | ||
421 | [IB_QPT_UC] = (IB_QP_AV | | ||
422 | IB_QP_CUR_STATE | | ||
423 | IB_QP_ALT_PATH | | ||
424 | IB_QP_ACCESS_FLAGS | | ||
425 | IB_QP_PKEY_INDEX | | ||
426 | IB_QP_PATH_MIG_STATE), | ||
427 | [IB_QPT_RC] = (IB_QP_PORT | | ||
428 | IB_QP_AV | | ||
429 | IB_QP_TIMEOUT | | ||
430 | IB_QP_RETRY_CNT | | ||
431 | IB_QP_RNR_RETRY | | ||
432 | IB_QP_MAX_QP_RD_ATOMIC | | ||
433 | IB_QP_MAX_DEST_RD_ATOMIC | | ||
434 | IB_QP_CUR_STATE | | ||
435 | IB_QP_ALT_PATH | | ||
436 | IB_QP_ACCESS_FLAGS | | ||
437 | IB_QP_PKEY_INDEX | | ||
438 | IB_QP_MIN_RNR_TIMER | | ||
439 | IB_QP_PATH_MIG_STATE), | ||
440 | [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | | ||
441 | IB_QP_QKEY), | ||
442 | [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | | ||
443 | IB_QP_QKEY), | ||
444 | } | ||
445 | } | ||
446 | }, | ||
447 | [IB_QPS_SQE] = { | ||
448 | [IB_QPS_RESET] = { .valid = 1 }, | ||
449 | [IB_QPS_ERR] = { .valid = 1 }, | ||
450 | [IB_QPS_RTS] = { | ||
451 | .valid = 1, | ||
452 | .opt_param = { | ||
453 | [IB_QPT_UD] = (IB_QP_CUR_STATE | | ||
454 | IB_QP_QKEY), | ||
455 | [IB_QPT_UC] = (IB_QP_CUR_STATE | | ||
456 | IB_QP_ACCESS_FLAGS), | ||
457 | [IB_QPT_SMI] = (IB_QP_CUR_STATE | | ||
458 | IB_QP_QKEY), | ||
459 | [IB_QPT_GSI] = (IB_QP_CUR_STATE | | ||
460 | IB_QP_QKEY), | ||
461 | } | ||
462 | } | ||
463 | }, | ||
464 | [IB_QPS_ERR] = { | ||
465 | [IB_QPS_RESET] = { .valid = 1 }, | ||
466 | [IB_QPS_ERR] = { .valid = 1 } | ||
467 | } | ||
468 | }; | ||
469 | |||
470 | int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state, | ||
471 | enum ib_qp_type type, enum ib_qp_attr_mask mask) | ||
472 | { | ||
473 | enum ib_qp_attr_mask req_param, opt_param; | ||
474 | |||
475 | if (cur_state < 0 || cur_state > IB_QPS_ERR || | ||
476 | next_state < 0 || next_state > IB_QPS_ERR) | ||
477 | return 0; | ||
478 | |||
479 | if (mask & IB_QP_CUR_STATE && | ||
480 | cur_state != IB_QPS_RTR && cur_state != IB_QPS_RTS && | ||
481 | cur_state != IB_QPS_SQD && cur_state != IB_QPS_SQE) | ||
482 | return 0; | ||
483 | |||
484 | if (!qp_state_table[cur_state][next_state].valid) | ||
485 | return 0; | ||
486 | |||
487 | req_param = qp_state_table[cur_state][next_state].req_param[type]; | ||
488 | opt_param = qp_state_table[cur_state][next_state].opt_param[type]; | ||
489 | |||
490 | if ((mask & req_param) != req_param) | ||
491 | return 0; | ||
492 | |||
493 | if (mask & ~(req_param | opt_param | IB_QP_STATE)) | ||
494 | return 0; | ||
495 | |||
496 | return 1; | ||
497 | } | ||
498 | EXPORT_SYMBOL(ib_modify_qp_is_ok); | ||
499 | |||
248 | int ib_modify_qp(struct ib_qp *qp, | 500 | int ib_modify_qp(struct ib_qp *qp, |
249 | struct ib_qp_attr *qp_attr, | 501 | struct ib_qp_attr *qp_attr, |
250 | int qp_attr_mask) | 502 | int qp_attr_mask) |