aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2017-11-12 08:15:10 -0500
committerSaeed Mahameed <saeedm@mellanox.com>2018-01-09 00:40:48 -0500
commit18e568c390c61682e747178f136bcbc45c707882 (patch)
treeb0df11b1703e5ebf62b49819f99c5231fb74b1b7
parent40817cdbb695de49fb1bfe857b0f440541cb22d8 (diff)
net/mlx5: Hairpin pair core object setup
Low level code to setup hairpin pair core object, deals with: - create hairpin RQs/SQs - destroy hairpin RQs/SQs - modifying hairpin RQs/SQs - pairing (rst2rdy) and unpairing (rdy2rst) Unlike conventional RQs/SQs, the memory used for the packet and descriptor buffers is allocated by the firmware and not the driver. The driver sets the overall data size (log). Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/transobj.c184
-rw-r--r--include/linux/mlx5/transobj.h19
2 files changed, 203 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/transobj.c b/drivers/net/ethernet/mellanox/mlx5/core/transobj.c
index 5e128d7a9ffd..a09ebbaf3b68 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/transobj.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/transobj.c
@@ -398,3 +398,187 @@ void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn)
398 mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 398 mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
399} 399}
400EXPORT_SYMBOL(mlx5_core_destroy_rqt); 400EXPORT_SYMBOL(mlx5_core_destroy_rqt);
401
402static int mlx5_hairpin_create_rq(struct mlx5_core_dev *mdev,
403 struct mlx5_hairpin_params *params, u32 *rqn)
404{
405 u32 in[MLX5_ST_SZ_DW(create_rq_in)] = {0};
406 void *rqc, *wq;
407
408 rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);
409 wq = MLX5_ADDR_OF(rqc, rqc, wq);
410
411 MLX5_SET(rqc, rqc, hairpin, 1);
412 MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST);
413 MLX5_SET(rqc, rqc, counter_set_id, params->q_counter);
414
415 MLX5_SET(wq, wq, log_hairpin_data_sz, params->log_data_size);
416
417 return mlx5_core_create_rq(mdev, in, MLX5_ST_SZ_BYTES(create_rq_in), rqn);
418}
419
420static int mlx5_hairpin_create_sq(struct mlx5_core_dev *mdev,
421 struct mlx5_hairpin_params *params, u32 *sqn)
422{
423 u32 in[MLX5_ST_SZ_DW(create_sq_in)] = {0};
424 void *sqc, *wq;
425
426 sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
427 wq = MLX5_ADDR_OF(sqc, sqc, wq);
428
429 MLX5_SET(sqc, sqc, hairpin, 1);
430 MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);
431
432 MLX5_SET(wq, wq, log_hairpin_data_sz, params->log_data_size);
433
434 return mlx5_core_create_sq(mdev, in, MLX5_ST_SZ_BYTES(create_sq_in), sqn);
435}
436
437static int mlx5_hairpin_create_queues(struct mlx5_hairpin *hp,
438 struct mlx5_hairpin_params *params)
439{
440 int err;
441
442 err = mlx5_hairpin_create_rq(hp->func_mdev, params, &hp->rqn);
443 if (err)
444 goto out_err_rq;
445
446 err = mlx5_hairpin_create_sq(hp->peer_mdev, params, &hp->sqn);
447 if (err)
448 goto out_err_sq;
449
450 return 0;
451
452out_err_sq:
453 mlx5_core_destroy_rq(hp->func_mdev, hp->rqn);
454out_err_rq:
455 return err;
456}
457
458static void mlx5_hairpin_destroy_queues(struct mlx5_hairpin *hp)
459{
460 mlx5_core_destroy_rq(hp->func_mdev, hp->rqn);
461 mlx5_core_destroy_sq(hp->peer_mdev, hp->sqn);
462}
463
464static int mlx5_hairpin_modify_rq(struct mlx5_core_dev *func_mdev, u32 rqn,
465 int curr_state, int next_state,
466 u16 peer_vhca, u32 peer_sq)
467{
468 u32 in[MLX5_ST_SZ_DW(modify_rq_in)] = {0};
469 void *rqc;
470
471 rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);
472
473 if (next_state == MLX5_RQC_STATE_RDY) {
474 MLX5_SET(rqc, rqc, hairpin_peer_sq, peer_sq);
475 MLX5_SET(rqc, rqc, hairpin_peer_vhca, peer_vhca);
476 }
477
478 MLX5_SET(modify_rq_in, in, rq_state, curr_state);
479 MLX5_SET(rqc, rqc, state, next_state);
480
481 return mlx5_core_modify_rq(func_mdev, rqn,
482 in, MLX5_ST_SZ_BYTES(modify_rq_in));
483}
484
485static int mlx5_hairpin_modify_sq(struct mlx5_core_dev *peer_mdev, u32 sqn,
486 int curr_state, int next_state,
487 u16 peer_vhca, u32 peer_rq)
488{
489 u32 in[MLX5_ST_SZ_DW(modify_sq_in)] = {0};
490 void *sqc;
491
492 sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
493
494 if (next_state == MLX5_RQC_STATE_RDY) {
495 MLX5_SET(sqc, sqc, hairpin_peer_rq, peer_rq);
496 MLX5_SET(sqc, sqc, hairpin_peer_vhca, peer_vhca);
497 }
498
499 MLX5_SET(modify_sq_in, in, sq_state, curr_state);
500 MLX5_SET(sqc, sqc, state, next_state);
501
502 return mlx5_core_modify_sq(peer_mdev, sqn,
503 in, MLX5_ST_SZ_BYTES(modify_sq_in));
504}
505
506static int mlx5_hairpin_pair_queues(struct mlx5_hairpin *hp)
507{
508 int err;
509
510 /* set peer SQ */
511 err = mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn,
512 MLX5_SQC_STATE_RST, MLX5_SQC_STATE_RDY,
513 MLX5_CAP_GEN(hp->func_mdev, vhca_id), hp->rqn);
514 if (err)
515 goto err_modify_sq;
516
517 /* set func RQ */
518 err = mlx5_hairpin_modify_rq(hp->func_mdev, hp->rqn,
519 MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY,
520 MLX5_CAP_GEN(hp->peer_mdev, vhca_id), hp->sqn);
521
522 if (err)
523 goto err_modify_rq;
524
525 return 0;
526
527err_modify_rq:
528 mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn, MLX5_SQC_STATE_RDY,
529 MLX5_SQC_STATE_RST, 0, 0);
530err_modify_sq:
531 return err;
532}
533
534static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp)
535{
536 /* unset func RQ */
537 mlx5_hairpin_modify_rq(hp->func_mdev, hp->rqn, MLX5_RQC_STATE_RDY,
538 MLX5_RQC_STATE_RST, 0, 0);
539
540 /* unset peer SQ */
541 mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn, MLX5_SQC_STATE_RDY,
542 MLX5_SQC_STATE_RST, 0, 0);
543}
544
545struct mlx5_hairpin *
546mlx5_core_hairpin_create(struct mlx5_core_dev *func_mdev,
547 struct mlx5_core_dev *peer_mdev,
548 struct mlx5_hairpin_params *params)
549{
550 struct mlx5_hairpin *hp;
551 int size, err;
552
553 size = sizeof(*hp);
554 hp = kzalloc(size, GFP_KERNEL);
555 if (!hp)
556 return ERR_PTR(-ENOMEM);
557
558 hp->func_mdev = func_mdev;
559 hp->peer_mdev = peer_mdev;
560
561 /* alloc and pair func --> peer hairpin */
562 err = mlx5_hairpin_create_queues(hp, params);
563 if (err)
564 goto err_create_queues;
565
566 err = mlx5_hairpin_pair_queues(hp);
567 if (err)
568 goto err_pair_queues;
569
570 return hp;
571
572err_pair_queues:
573 mlx5_hairpin_destroy_queues(hp);
574err_create_queues:
575 kfree(hp);
576 return ERR_PTR(err);
577}
578
579void mlx5_core_hairpin_destroy(struct mlx5_hairpin *hp)
580{
581 mlx5_hairpin_unpair_queues(hp);
582 mlx5_hairpin_destroy_queues(hp);
583 kfree(hp);
584}
diff --git a/include/linux/mlx5/transobj.h b/include/linux/mlx5/transobj.h
index 88441f5ece25..a228310c1968 100644
--- a/include/linux/mlx5/transobj.h
+++ b/include/linux/mlx5/transobj.h
@@ -75,4 +75,23 @@ int mlx5_core_modify_rqt(struct mlx5_core_dev *dev, u32 rqtn, u32 *in,
75 int inlen); 75 int inlen);
76void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn); 76void mlx5_core_destroy_rqt(struct mlx5_core_dev *dev, u32 rqtn);
77 77
78struct mlx5_hairpin_params {
79 u8 log_data_size;
80 u16 q_counter;
81};
82
83struct mlx5_hairpin {
84 struct mlx5_core_dev *func_mdev;
85 struct mlx5_core_dev *peer_mdev;
86
87 u32 rqn;
88 u32 sqn;
89};
90
91struct mlx5_hairpin *
92mlx5_core_hairpin_create(struct mlx5_core_dev *func_mdev,
93 struct mlx5_core_dev *peer_mdev,
94 struct mlx5_hairpin_params *params);
95
96void mlx5_core_hairpin_destroy(struct mlx5_hairpin *pair);
78#endif /* __TRANSOBJ_H__ */ 97#endif /* __TRANSOBJ_H__ */