File Index
Files and directories
Sign in
FILE

otx2_devlink.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Marvell RVU PF/VF Netdev Devlink
  3 *
  4 * Copyright (C) 2021 Marvell.
  5 */
  6
  7#include "otx2_common.h"
  8
  9/* Devlink Params APIs */
 10static int otx2_dl_mcam_count_validate(struct devlink *devlink, u32 id,
 11				       union devlink_param_value val,
 12				       struct netlink_ext_ack *extack)
 13{
 14	struct otx2_devlink *otx2_dl = devlink_priv(devlink);
 15	struct otx2_nic *pfvf = otx2_dl->pfvf;
 16	struct otx2_flow_config *flow_cfg;
 17
 18	if (!pfvf->flow_cfg) {
 19		NL_SET_ERR_MSG_MOD(extack,
 20				   "pfvf->flow_cfg not initialized");
 21		return -EINVAL;
 22	}
 23
 24	flow_cfg = pfvf->flow_cfg;
 25	if (flow_cfg && flow_cfg->nr_flows) {
 26		NL_SET_ERR_MSG_MOD(extack,
 27				   "Cannot modify count when there are active rules");
 28		return -EINVAL;
 29	}
 30
 31	return 0;
 32}
 33
 34static int otx2_dl_mcam_count_set(struct devlink *devlink, u32 id,
 35				  struct devlink_param_gset_ctx *ctx,
 36				  struct netlink_ext_ack *extack)
 37{
 38	struct otx2_devlink *otx2_dl = devlink_priv(devlink);
 39	struct otx2_nic *pfvf = otx2_dl->pfvf;
 40
 41	if (!pfvf->flow_cfg)
 42		return 0;
 43
 44	pfvf->flow_cfg->ntuple_cnt = ctx->val.vu16;
 45	otx2_alloc_mcam_entries(pfvf, ctx->val.vu16);
 46
 47	return 0;
 48}
 49
 50static int otx2_dl_mcam_count_get(struct devlink *devlink, u32 id,
 51				  struct devlink_param_gset_ctx *ctx,
 52				  struct netlink_ext_ack *extack)
 53{
 54	struct otx2_devlink *otx2_dl = devlink_priv(devlink);
 55	struct otx2_nic *pfvf = otx2_dl->pfvf;
 56	struct otx2_flow_config *flow_cfg;
 57
 58	if (!pfvf->flow_cfg) {
 59		ctx->val.vu16 = 0;
 60		return 0;
 61	}
 62
 63	flow_cfg = pfvf->flow_cfg;
 64	ctx->val.vu16 = flow_cfg->max_flows;
 65
 66	return 0;
 67}
 68
 69static int otx2_dl_ucast_flt_cnt_set(struct devlink *devlink, u32 id,
 70				     struct devlink_param_gset_ctx *ctx,
 71				     struct netlink_ext_ack *extack)
 72{
 73	struct otx2_devlink *otx2_dl = devlink_priv(devlink);
 74	struct otx2_nic *pfvf = otx2_dl->pfvf;
 75	int err;
 76
 77	pfvf->flow_cfg->ucast_flt_cnt = ctx->val.vu8;
 78
 79	otx2_mcam_flow_del(pfvf);
 80	err = otx2_mcam_entry_init(pfvf);
 81	if (err)
 82		return err;
 83
 84	return 0;
 85}
 86
 87static int otx2_dl_ucast_flt_cnt_get(struct devlink *devlink, u32 id,
 88				     struct devlink_param_gset_ctx *ctx,
 89				     struct netlink_ext_ack *extack)
 90{
 91	struct otx2_devlink *otx2_dl = devlink_priv(devlink);
 92	struct otx2_nic *pfvf = otx2_dl->pfvf;
 93
 94	ctx->val.vu8 = pfvf->flow_cfg ? pfvf->flow_cfg->ucast_flt_cnt : 0;
 95
 96	return 0;
 97}
 98
 99static int otx2_dl_ucast_flt_cnt_validate(struct devlink *devlink, u32 id,
100					  union devlink_param_value val,
101					  struct netlink_ext_ack *extack)
102{
103	struct otx2_devlink *otx2_dl = devlink_priv(devlink);
104	struct otx2_nic *pfvf = otx2_dl->pfvf;
105
106	/* Check for UNICAST filter support*/
107	if (!(pfvf->flags & OTX2_FLAG_UCAST_FLTR_SUPPORT)) {
108		NL_SET_ERR_MSG_MOD(extack,
109				   "Unicast filter not enabled");
110		return -EINVAL;
111	}
112
113	if (!pfvf->flow_cfg) {
114		NL_SET_ERR_MSG_MOD(extack,
115				   "pfvf->flow_cfg not initialized");
116		return -EINVAL;
117	}
118
119	if (pfvf->flow_cfg->nr_flows) {
120		NL_SET_ERR_MSG_MOD(extack,
121				   "Cannot modify count when there are active rules");
122		return -EINVAL;
123	}
124
125	return 0;
126}
127
128enum otx2_dl_param_id {
129	OTX2_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
130	OTX2_DEVLINK_PARAM_ID_MCAM_COUNT,
131	OTX2_DEVLINK_PARAM_ID_UCAST_FLT_CNT,
132};
133
134static const struct devlink_param otx2_dl_params[] = {
135	DEVLINK_PARAM_DRIVER(OTX2_DEVLINK_PARAM_ID_MCAM_COUNT,
136			     "mcam_count", DEVLINK_PARAM_TYPE_U16,
137			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
138			     otx2_dl_mcam_count_get, otx2_dl_mcam_count_set,
139			     otx2_dl_mcam_count_validate),
140	DEVLINK_PARAM_DRIVER(OTX2_DEVLINK_PARAM_ID_UCAST_FLT_CNT,
141			     "unicast_filter_count", DEVLINK_PARAM_TYPE_U8,
142			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
143			     otx2_dl_ucast_flt_cnt_get, otx2_dl_ucast_flt_cnt_set,
144			     otx2_dl_ucast_flt_cnt_validate),
145};
146
147#ifdef CONFIG_RVU_ESWITCH
148static int otx2_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
149{
150	struct otx2_devlink *otx2_dl = devlink_priv(devlink);
151	struct otx2_nic *pfvf = otx2_dl->pfvf;
152
153	if (!otx2_rep_dev(pfvf->pdev))
154		return -EOPNOTSUPP;
155
156	*mode = pfvf->esw_mode;
157
158	return 0;
159}
160
161static int otx2_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
162					 struct netlink_ext_ack *extack)
163{
164	struct otx2_devlink *otx2_dl = devlink_priv(devlink);
165	struct otx2_nic *pfvf = otx2_dl->pfvf;
166	int ret = 0;
167
168	if (!otx2_rep_dev(pfvf->pdev))
169		return -EOPNOTSUPP;
170
171	if (pfvf->esw_mode == mode)
172		return 0;
173
174	switch (mode) {
175	case DEVLINK_ESWITCH_MODE_LEGACY:
176		rvu_rep_destroy(pfvf);
177		break;
178	case DEVLINK_ESWITCH_MODE_SWITCHDEV:
179		ret = rvu_rep_create(pfvf, extack);
180		break;
181	default:
182		return -EINVAL;
183	}
184
185	if (!ret)
186		pfvf->esw_mode = mode;
187
188	return ret;
189}
190#endif
191
192static const struct devlink_ops otx2_devlink_ops = {
193#ifdef CONFIG_RVU_ESWITCH
194	.eswitch_mode_get = otx2_devlink_eswitch_mode_get,
195	.eswitch_mode_set = otx2_devlink_eswitch_mode_set,
196#endif
197};
198
199int otx2_register_dl(struct otx2_nic *pfvf)
200{
201	struct otx2_devlink *otx2_dl;
202	struct devlink *dl;
203	int err;
204
205	dl = devlink_alloc(&otx2_devlink_ops,
206			   sizeof(struct otx2_devlink), pfvf->dev);
207	if (!dl) {
208		dev_warn(pfvf->dev, "devlink_alloc failed\n");
209		return -ENOMEM;
210	}
211
212	otx2_dl = devlink_priv(dl);
213	otx2_dl->dl = dl;
214	otx2_dl->pfvf = pfvf;
215	pfvf->dl = otx2_dl;
216
217	err = devlink_params_register(dl, otx2_dl_params,
218				      ARRAY_SIZE(otx2_dl_params));
219	if (err) {
220		dev_err(pfvf->dev,
221			"devlink params register failed with error %d", err);
222		goto err_dl;
223	}
224
225	devlink_register(dl);
226	return 0;
227
228err_dl:
229	devlink_free(dl);
230	return err;
231}
232EXPORT_SYMBOL(otx2_register_dl);
233
234void otx2_unregister_dl(struct otx2_nic *pfvf)
235{
236	struct otx2_devlink *otx2_dl = pfvf->dl;
237	struct devlink *dl = otx2_dl->dl;
238
239	devlink_unregister(dl);
240	devlink_params_unregister(dl, otx2_dl_params,
241				  ARRAY_SIZE(otx2_dl_params));
242	devlink_free(dl);
243}
244EXPORT_SYMBOL(otx2_unregister_dl);
~/ Read-only file preview.