aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/verbs.c252
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}
246EXPORT_SYMBOL(ib_create_qp); 246EXPORT_SYMBOL(ib_create_qp);
247 247
248static 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
470int 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}
498EXPORT_SYMBOL(ib_modify_qp_is_ok);
499
248int ib_modify_qp(struct ib_qp *qp, 500int 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)