152306deeSIgor Russkikh // SPDX-License-Identifier: GPL-2.0-or-later
252306deeSIgor Russkikh /* Marvell/Qlogic FastLinQ NIC driver
352306deeSIgor Russkikh  *
452306deeSIgor Russkikh  * Copyright (C) 2020 Marvell International Ltd.
552306deeSIgor Russkikh  */
652306deeSIgor Russkikh 
752306deeSIgor Russkikh #include <linux/kernel.h>
8755f982bSIgor Russkikh #include <linux/qed/qed_if.h>
952306deeSIgor Russkikh #include "qed.h"
1052306deeSIgor Russkikh #include "qed_devlink.h"
1152306deeSIgor Russkikh 
1252306deeSIgor Russkikh enum qed_devlink_param_id {
1352306deeSIgor Russkikh 	QED_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
1452306deeSIgor Russkikh 	QED_DEVLINK_PARAM_ID_IWARP_CMT,
1552306deeSIgor Russkikh };
1652306deeSIgor Russkikh 
1752306deeSIgor Russkikh static int qed_dl_param_get(struct devlink *dl, u32 id,
1852306deeSIgor Russkikh 			    struct devlink_param_gset_ctx *ctx)
1952306deeSIgor Russkikh {
20755f982bSIgor Russkikh 	struct qed_devlink *qed_dl = devlink_priv(dl);
2152306deeSIgor Russkikh 	struct qed_dev *cdev;
2252306deeSIgor Russkikh 
2352306deeSIgor Russkikh 	cdev = qed_dl->cdev;
2452306deeSIgor Russkikh 	ctx->val.vbool = cdev->iwarp_cmt;
2552306deeSIgor Russkikh 
2652306deeSIgor Russkikh 	return 0;
2752306deeSIgor Russkikh }
2852306deeSIgor Russkikh 
2952306deeSIgor Russkikh static int qed_dl_param_set(struct devlink *dl, u32 id,
3052306deeSIgor Russkikh 			    struct devlink_param_gset_ctx *ctx)
3152306deeSIgor Russkikh {
32755f982bSIgor Russkikh 	struct qed_devlink *qed_dl = devlink_priv(dl);
3352306deeSIgor Russkikh 	struct qed_dev *cdev;
3452306deeSIgor Russkikh 
3552306deeSIgor Russkikh 	cdev = qed_dl->cdev;
3652306deeSIgor Russkikh 	cdev->iwarp_cmt = ctx->val.vbool;
3752306deeSIgor Russkikh 
3852306deeSIgor Russkikh 	return 0;
3952306deeSIgor Russkikh }
4052306deeSIgor Russkikh 
4152306deeSIgor Russkikh static const struct devlink_param qed_devlink_params[] = {
4252306deeSIgor Russkikh 	DEVLINK_PARAM_DRIVER(QED_DEVLINK_PARAM_ID_IWARP_CMT,
4352306deeSIgor Russkikh 			     "iwarp_cmt", DEVLINK_PARAM_TYPE_BOOL,
4452306deeSIgor Russkikh 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
4552306deeSIgor Russkikh 			     qed_dl_param_get, qed_dl_param_set, NULL),
4652306deeSIgor Russkikh };
4752306deeSIgor Russkikh 
4852306deeSIgor Russkikh static const struct devlink_ops qed_dl_ops;
4952306deeSIgor Russkikh 
50755f982bSIgor Russkikh struct devlink *qed_devlink_register(struct qed_dev *cdev)
5152306deeSIgor Russkikh {
5252306deeSIgor Russkikh 	union devlink_param_value value;
53755f982bSIgor Russkikh 	struct qed_devlink *qdevlink;
5452306deeSIgor Russkikh 	struct devlink *dl;
5552306deeSIgor Russkikh 	int rc;
5652306deeSIgor Russkikh 
57755f982bSIgor Russkikh 	dl = devlink_alloc(&qed_dl_ops, sizeof(struct qed_devlink));
5852306deeSIgor Russkikh 	if (!dl)
59755f982bSIgor Russkikh 		return ERR_PTR(-ENOMEM);
6052306deeSIgor Russkikh 
61755f982bSIgor Russkikh 	qdevlink = devlink_priv(dl);
62755f982bSIgor Russkikh 	qdevlink->cdev = cdev;
6352306deeSIgor Russkikh 
6452306deeSIgor Russkikh 	rc = devlink_register(dl, &cdev->pdev->dev);
6552306deeSIgor Russkikh 	if (rc)
6652306deeSIgor Russkikh 		goto err_free;
6752306deeSIgor Russkikh 
6852306deeSIgor Russkikh 	rc = devlink_params_register(dl, qed_devlink_params,
6952306deeSIgor Russkikh 				     ARRAY_SIZE(qed_devlink_params));
7052306deeSIgor Russkikh 	if (rc)
7152306deeSIgor Russkikh 		goto err_unregister;
7252306deeSIgor Russkikh 
7352306deeSIgor Russkikh 	value.vbool = false;
7452306deeSIgor Russkikh 	devlink_param_driverinit_value_set(dl,
7552306deeSIgor Russkikh 					   QED_DEVLINK_PARAM_ID_IWARP_CMT,
7652306deeSIgor Russkikh 					   value);
7752306deeSIgor Russkikh 
7852306deeSIgor Russkikh 	devlink_params_publish(dl);
7952306deeSIgor Russkikh 	cdev->iwarp_cmt = false;
8052306deeSIgor Russkikh 
81755f982bSIgor Russkikh 	return dl;
8252306deeSIgor Russkikh 
8352306deeSIgor Russkikh err_unregister:
8452306deeSIgor Russkikh 	devlink_unregister(dl);
8552306deeSIgor Russkikh 
8652306deeSIgor Russkikh err_free:
8752306deeSIgor Russkikh 	devlink_free(dl);
8852306deeSIgor Russkikh 
89755f982bSIgor Russkikh 	return ERR_PTR(rc);
9052306deeSIgor Russkikh }
9152306deeSIgor Russkikh 
92755f982bSIgor Russkikh void qed_devlink_unregister(struct devlink *devlink)
9352306deeSIgor Russkikh {
94755f982bSIgor Russkikh 	if (!devlink)
9552306deeSIgor Russkikh 		return;
9652306deeSIgor Russkikh 
97755f982bSIgor Russkikh 	devlink_params_unregister(devlink, qed_devlink_params,
9852306deeSIgor Russkikh 				  ARRAY_SIZE(qed_devlink_params));
9952306deeSIgor Russkikh 
100755f982bSIgor Russkikh 	devlink_unregister(devlink);
101755f982bSIgor Russkikh 	devlink_free(devlink);
10252306deeSIgor Russkikh }
103