xref: /linux/net/devlink/param.c (revision eb7b4d458e0d6833ffbb717edf4282f5ca6a7b57)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
4  * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
5  */
6 
7 #include "devl_internal.h"
8 
9 static const struct devlink_param devlink_param_generic[] = {
10 	{
11 		.id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
12 		.name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
13 		.type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
14 	},
15 	{
16 		.id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
17 		.name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
18 		.type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
19 	},
20 	{
21 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
22 		.name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
23 		.type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
24 	},
25 	{
26 		.id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
27 		.name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
28 		.type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
29 	},
30 	{
31 		.id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
32 		.name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
33 		.type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
34 	},
35 	{
36 		.id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
37 		.name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
38 		.type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
39 	},
40 	{
41 		.id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
42 		.name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
43 		.type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
44 	},
45 	{
46 		.id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
47 		.name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
48 		.type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
49 	},
50 	{
51 		.id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
52 		.name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
53 		.type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
54 	},
55 	{
56 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
57 		.name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
58 		.type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
59 	},
60 	{
61 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
62 		.name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
63 		.type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
64 	},
65 	{
66 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
67 		.name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
68 		.type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
69 	},
70 	{
71 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
72 		.name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
73 		.type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
74 	},
75 	{
76 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
77 		.name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
78 		.type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
79 	},
80 	{
81 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
82 		.name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
83 		.type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
84 	},
85 	{
86 		.id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
87 		.name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
88 		.type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
89 	},
90 	{
91 		.id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
92 		.name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
93 		.type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
94 	},
95 	{
96 		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC,
97 		.name = DEVLINK_PARAM_GENERIC_ENABLE_PHC_NAME,
98 		.type = DEVLINK_PARAM_GENERIC_ENABLE_PHC_TYPE,
99 	},
100 	{
101 		.id = DEVLINK_PARAM_GENERIC_ID_CLOCK_ID,
102 		.name = DEVLINK_PARAM_GENERIC_CLOCK_ID_NAME,
103 		.type = DEVLINK_PARAM_GENERIC_CLOCK_ID_TYPE,
104 	},
105 	{
106 		.id = DEVLINK_PARAM_GENERIC_ID_TOTAL_VFS,
107 		.name = DEVLINK_PARAM_GENERIC_TOTAL_VFS_NAME,
108 		.type = DEVLINK_PARAM_GENERIC_TOTAL_VFS_TYPE,
109 	},
110 	{
111 		.id = DEVLINK_PARAM_GENERIC_ID_NUM_DOORBELLS,
112 		.name = DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_NAME,
113 		.type = DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_TYPE,
114 	},
115 	{
116 		.id = DEVLINK_PARAM_GENERIC_ID_MAX_MAC_PER_VF,
117 		.name = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_NAME,
118 		.type = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_TYPE,
119 	},
120 };
121 
122 static int devlink_param_generic_verify(const struct devlink_param *param)
123 {
124 	/* verify it match generic parameter by id and name */
125 	if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
126 		return -EINVAL;
127 	if (strcmp(param->name, devlink_param_generic[param->id].name))
128 		return -ENOENT;
129 
130 	WARN_ON(param->type != devlink_param_generic[param->id].type);
131 
132 	return 0;
133 }
134 
135 static int devlink_param_driver_verify(const struct devlink_param *param)
136 {
137 	int i;
138 
139 	if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
140 		return -EINVAL;
141 	/* verify no such name in generic params */
142 	for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
143 		if (!strcmp(param->name, devlink_param_generic[i].name))
144 			return -EEXIST;
145 
146 	return 0;
147 }
148 
149 static struct devlink_param_item *
150 devlink_param_find_by_name(struct xarray *params, const char *param_name)
151 {
152 	struct devlink_param_item *param_item;
153 	unsigned long param_id;
154 
155 	xa_for_each(params, param_id, param_item) {
156 		if (!strcmp(param_item->param->name, param_name))
157 			return param_item;
158 	}
159 	return NULL;
160 }
161 
162 static struct devlink_param_item *
163 devlink_param_find_by_id(struct xarray *params, u32 param_id)
164 {
165 	return xa_load(params, param_id);
166 }
167 
168 static bool
169 devlink_param_cmode_is_supported(const struct devlink_param *param,
170 				 enum devlink_param_cmode cmode)
171 {
172 	return test_bit(cmode, &param->supported_cmodes);
173 }
174 
175 static int devlink_param_get(struct devlink *devlink,
176 			     const struct devlink_param *param,
177 			     struct devlink_param_gset_ctx *ctx,
178 			     struct netlink_ext_ack *extack)
179 {
180 	if (!param->get)
181 		return -EOPNOTSUPP;
182 	return param->get(devlink, param->id, ctx, extack);
183 }
184 
185 static int devlink_param_set(struct devlink *devlink,
186 			     const struct devlink_param *param,
187 			     struct devlink_param_gset_ctx *ctx,
188 			     struct netlink_ext_ack *extack)
189 {
190 	if (!param->set)
191 		return -EOPNOTSUPP;
192 	return param->set(devlink, param->id, ctx, extack);
193 }
194 
195 static int devlink_param_get_default(struct devlink *devlink,
196 				     const struct devlink_param *param,
197 				     struct devlink_param_gset_ctx *ctx,
198 				     struct netlink_ext_ack *extack)
199 {
200 	if (!param->get_default)
201 		return -EOPNOTSUPP;
202 
203 	return param->get_default(devlink, param->id, ctx, extack);
204 }
205 
206 static int devlink_param_reset_default(struct devlink *devlink,
207 				       const struct devlink_param *param,
208 				       enum devlink_param_cmode cmode,
209 				       struct netlink_ext_ack *extack)
210 {
211 	if (!param->reset_default)
212 		return -EOPNOTSUPP;
213 
214 	return param->reset_default(devlink, param->id, cmode, extack);
215 }
216 
217 static int
218 devlink_nl_param_value_put(struct sk_buff *msg, enum devlink_param_type type,
219 			   int nla_type, union devlink_param_value *val,
220 			   bool flag_as_u8)
221 {
222 	switch (type) {
223 	case DEVLINK_PARAM_TYPE_U8:
224 		if (nla_put_u8(msg, nla_type, val->vu8))
225 			return -EMSGSIZE;
226 		break;
227 	case DEVLINK_PARAM_TYPE_U16:
228 		if (nla_put_u16(msg, nla_type, val->vu16))
229 			return -EMSGSIZE;
230 		break;
231 	case DEVLINK_PARAM_TYPE_U32:
232 		if (nla_put_u32(msg, nla_type, val->vu32))
233 			return -EMSGSIZE;
234 		break;
235 	case DEVLINK_PARAM_TYPE_U64:
236 		if (devlink_nl_put_u64(msg, nla_type, val->vu64))
237 			return -EMSGSIZE;
238 		break;
239 	case DEVLINK_PARAM_TYPE_STRING:
240 		if (nla_put_string(msg, nla_type, val->vstr))
241 			return -EMSGSIZE;
242 		break;
243 	case DEVLINK_PARAM_TYPE_BOOL:
244 		/* default values of type bool are encoded with u8, so that
245 		 * false can be distinguished from not present
246 		 */
247 		if (flag_as_u8) {
248 			if (nla_put_u8(msg, nla_type, val->vbool))
249 				return -EMSGSIZE;
250 		} else {
251 			if (val->vbool && nla_put_flag(msg, nla_type))
252 				return -EMSGSIZE;
253 		}
254 		break;
255 	case DEVLINK_PARAM_TYPE_U64_ARRAY:
256 		if (val->u64arr.size > __DEVLINK_PARAM_MAX_ARRAY_SIZE)
257 			return -EMSGSIZE;
258 
259 		for (int i = 0; i < val->u64arr.size; i++) {
260 			if (nla_put_uint(msg, nla_type, val->u64arr.val[i]))
261 				return -EMSGSIZE;
262 		}
263 		break;
264 	}
265 	return 0;
266 }
267 
268 static int
269 devlink_nl_param_value_fill_one(struct sk_buff *msg,
270 				enum devlink_param_type type,
271 				enum devlink_param_cmode cmode,
272 				union devlink_param_value *val,
273 				union devlink_param_value *default_val,
274 				bool has_default)
275 {
276 	struct nlattr *param_value_attr;
277 	int err = -EMSGSIZE;
278 
279 	param_value_attr = nla_nest_start_noflag(msg,
280 						 DEVLINK_ATTR_PARAM_VALUE);
281 	if (!param_value_attr)
282 		return -EMSGSIZE;
283 
284 	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
285 		goto value_nest_cancel;
286 
287 	err = devlink_nl_param_value_put(msg, type,
288 					 DEVLINK_ATTR_PARAM_VALUE_DATA,
289 					 val, false);
290 	if (err)
291 		goto value_nest_cancel;
292 
293 	if (has_default) {
294 		err = devlink_nl_param_value_put(msg, type,
295 						 DEVLINK_ATTR_PARAM_VALUE_DEFAULT,
296 						 default_val, true);
297 		if (err)
298 			goto value_nest_cancel;
299 	}
300 
301 	nla_nest_end(msg, param_value_attr);
302 	return 0;
303 
304 value_nest_cancel:
305 	nla_nest_cancel(msg, param_value_attr);
306 	return err;
307 }
308 
309 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
310 				 unsigned int port_index,
311 				 struct devlink_param_item *param_item,
312 				 enum devlink_command cmd,
313 				 u32 portid, u32 seq, int flags,
314 				 struct netlink_ext_ack *extack)
315 {
316 	bool default_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
317 	bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
318 	const struct devlink_param *param = param_item->param;
319 	union devlink_param_value *default_value;
320 	union devlink_param_value *param_value;
321 	struct devlink_param_gset_ctx *ctx;
322 	struct nlattr *param_values_list;
323 	struct nlattr *param_attr;
324 	void *hdr;
325 	int err;
326 	int i;
327 
328 	default_value = kcalloc(DEVLINK_PARAM_CMODE_MAX + 1,
329 				sizeof(*default_value), GFP_KERNEL);
330 	if (!default_value)
331 		return -ENOMEM;
332 
333 	param_value = kcalloc(DEVLINK_PARAM_CMODE_MAX + 1,
334 			      sizeof(*param_value), GFP_KERNEL);
335 	if (!param_value) {
336 		kfree(default_value);
337 		return -ENOMEM;
338 	}
339 
340 	ctx = kzalloc_obj(*ctx);
341 	if (!ctx) {
342 		kfree(param_value);
343 		kfree(default_value);
344 		return -ENOMEM;
345 	}
346 
347 	/* Get value from driver part to driverinit configuration mode */
348 	for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
349 		if (!devlink_param_cmode_is_supported(param, i))
350 			continue;
351 		if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
352 			if (param_item->driverinit_value_new_valid) {
353 				param_value[i] = param_item->driverinit_value_new;
354 			} else if (param_item->driverinit_value_valid) {
355 				param_value[i] = param_item->driverinit_value;
356 			} else {
357 				err = -EOPNOTSUPP;
358 				goto get_put_fail;
359 			}
360 
361 			if (param_item->driverinit_value_valid) {
362 				default_value[i] = param_item->driverinit_default;
363 				default_value_set[i] = true;
364 			}
365 		} else {
366 			ctx->cmode = i;
367 			err = devlink_param_get(devlink, param, ctx, extack);
368 			if (err)
369 				goto get_put_fail;
370 
371 			param_value[i] = ctx->val;
372 
373 			err = devlink_param_get_default(devlink, param, ctx,
374 							extack);
375 			if (!err) {
376 				default_value[i] = ctx->val;
377 				default_value_set[i] = true;
378 			} else if (err != -EOPNOTSUPP) {
379 				goto get_put_fail;
380 			}
381 		}
382 		param_value_set[i] = true;
383 	}
384 
385 	err = -EMSGSIZE;
386 	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
387 	if (!hdr)
388 		goto get_put_fail;
389 
390 	if (devlink_nl_put_handle(msg, devlink))
391 		goto genlmsg_cancel;
392 
393 	if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
394 	    cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
395 	    cmd == DEVLINK_CMD_PORT_PARAM_DEL)
396 		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
397 			goto genlmsg_cancel;
398 
399 	param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
400 	if (!param_attr)
401 		goto genlmsg_cancel;
402 	if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
403 		goto param_nest_cancel;
404 	if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
405 		goto param_nest_cancel;
406 	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, param->type))
407 		goto param_nest_cancel;
408 
409 	param_values_list = nla_nest_start_noflag(msg,
410 						  DEVLINK_ATTR_PARAM_VALUES_LIST);
411 	if (!param_values_list)
412 		goto param_nest_cancel;
413 
414 	for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
415 		if (!param_value_set[i])
416 			continue;
417 		err = devlink_nl_param_value_fill_one(msg, param->type,
418 						      i, &param_value[i],
419 						      &default_value[i],
420 						      default_value_set[i]);
421 		if (err)
422 			goto values_list_nest_cancel;
423 	}
424 
425 	nla_nest_end(msg, param_values_list);
426 	nla_nest_end(msg, param_attr);
427 	genlmsg_end(msg, hdr);
428 	kfree(default_value);
429 	kfree(param_value);
430 	kfree(ctx);
431 	return 0;
432 
433 values_list_nest_cancel:
434 	nla_nest_end(msg, param_values_list);
435 param_nest_cancel:
436 	nla_nest_cancel(msg, param_attr);
437 genlmsg_cancel:
438 	genlmsg_cancel(msg, hdr);
439 get_put_fail:
440 	kfree(default_value);
441 	kfree(param_value);
442 	kfree(ctx);
443 	return err;
444 }
445 
446 static void devlink_param_notify(struct devlink *devlink,
447 				 unsigned int port_index,
448 				 struct devlink_param_item *param_item,
449 				 enum devlink_command cmd)
450 {
451 	struct sk_buff *msg;
452 	int err;
453 
454 	WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
455 		cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
456 		cmd != DEVLINK_CMD_PORT_PARAM_DEL);
457 
458 	/* devlink_notify_register() / devlink_notify_unregister()
459 	 * will replay the notifications if the params are added/removed
460 	 * outside of the lifetime of the instance.
461 	 */
462 	if (!devl_is_registered(devlink) || !devlink_nl_notify_need(devlink))
463 		return;
464 
465 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
466 	if (!msg)
467 		return;
468 	err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
469 				    0, 0, 0, NULL);
470 	if (err) {
471 		nlmsg_free(msg);
472 		return;
473 	}
474 
475 	devlink_nl_notify_send(devlink, msg);
476 }
477 
478 static void devlink_params_notify(struct devlink *devlink,
479 				  enum devlink_command cmd)
480 {
481 	struct devlink_param_item *param_item;
482 	unsigned long param_id;
483 
484 	xa_for_each(&devlink->params, param_id, param_item)
485 		devlink_param_notify(devlink, 0, param_item, cmd);
486 }
487 
488 void devlink_params_notify_register(struct devlink *devlink)
489 {
490 	devlink_params_notify(devlink, DEVLINK_CMD_PARAM_NEW);
491 }
492 
493 void devlink_params_notify_unregister(struct devlink *devlink)
494 {
495 	devlink_params_notify(devlink, DEVLINK_CMD_PARAM_DEL);
496 }
497 
498 static int devlink_nl_param_get_dump_one(struct sk_buff *msg,
499 					 struct devlink *devlink,
500 					 struct netlink_callback *cb,
501 					 int flags)
502 {
503 	struct devlink_nl_dump_state *state = devlink_dump_state(cb);
504 	struct devlink_param_item *param_item;
505 	unsigned long param_id;
506 	int err = 0;
507 
508 	xa_for_each_start(&devlink->params, param_id, param_item, state->idx) {
509 		err = devlink_nl_param_fill(msg, devlink, 0, param_item,
510 					    DEVLINK_CMD_PARAM_GET,
511 					    NETLINK_CB(cb->skb).portid,
512 					    cb->nlh->nlmsg_seq, flags,
513 					    cb->extack);
514 		if (err == -EOPNOTSUPP) {
515 			err = 0;
516 		} else if (err) {
517 			state->idx = param_id;
518 			break;
519 		}
520 	}
521 
522 	return err;
523 }
524 
525 int devlink_nl_param_get_dumpit(struct sk_buff *skb,
526 				struct netlink_callback *cb)
527 {
528 	return devlink_nl_dumpit(skb, cb, devlink_nl_param_get_dump_one);
529 }
530 
531 static int
532 devlink_param_type_get_from_info(struct genl_info *info,
533 				 enum devlink_param_type *param_type)
534 {
535 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
536 		return -EINVAL;
537 
538 	*param_type = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE]);
539 
540 	return 0;
541 }
542 
543 static int
544 devlink_param_value_get_from_info(const struct devlink_param *param,
545 				  struct genl_info *info,
546 				  union devlink_param_value *value)
547 {
548 	struct nlattr *param_data;
549 	int len, cnt, rem;
550 
551 	param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
552 
553 	if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
554 		return -EINVAL;
555 
556 	switch (param->type) {
557 	case DEVLINK_PARAM_TYPE_U8:
558 		if (nla_len(param_data) != sizeof(u8))
559 			return -EINVAL;
560 		value->vu8 = nla_get_u8(param_data);
561 		break;
562 	case DEVLINK_PARAM_TYPE_U16:
563 		if (nla_len(param_data) != sizeof(u16))
564 			return -EINVAL;
565 		value->vu16 = nla_get_u16(param_data);
566 		break;
567 	case DEVLINK_PARAM_TYPE_U32:
568 		if (nla_len(param_data) != sizeof(u32))
569 			return -EINVAL;
570 		value->vu32 = nla_get_u32(param_data);
571 		break;
572 	case DEVLINK_PARAM_TYPE_U64:
573 		if (nla_len(param_data) != sizeof(u64))
574 			return -EINVAL;
575 		value->vu64 = nla_get_u64(param_data);
576 		break;
577 	case DEVLINK_PARAM_TYPE_STRING:
578 		len = strnlen(nla_data(param_data), nla_len(param_data));
579 		if (len == nla_len(param_data) ||
580 		    len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
581 			return -EINVAL;
582 		strcpy(value->vstr, nla_data(param_data));
583 		break;
584 	case DEVLINK_PARAM_TYPE_BOOL:
585 		if (param_data && nla_len(param_data))
586 			return -EINVAL;
587 		value->vbool = nla_get_flag(param_data);
588 		break;
589 
590 	case DEVLINK_PARAM_TYPE_U64_ARRAY:
591 		cnt = 0;
592 		nla_for_each_attr_type(param_data,
593 				       DEVLINK_ATTR_PARAM_VALUE_DATA,
594 				       genlmsg_data(info->genlhdr),
595 				       genlmsg_len(info->genlhdr), rem) {
596 			if (cnt >= __DEVLINK_PARAM_MAX_ARRAY_SIZE)
597 				return -EMSGSIZE;
598 
599 			if ((nla_len(param_data) != sizeof(u64)) &&
600 			    (nla_len(param_data) != sizeof(u32))) {
601 				NL_SET_BAD_ATTR(info->extack, param_data);
602 				return -EINVAL;
603 			}
604 
605 			value->u64arr.val[cnt] = nla_get_uint(param_data);
606 			cnt++;
607 		}
608 
609 		value->u64arr.size = cnt;
610 		break;
611 	}
612 	return 0;
613 }
614 
615 static struct devlink_param_item *
616 devlink_param_get_from_info(struct xarray *params, struct genl_info *info)
617 {
618 	char *param_name;
619 
620 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME))
621 		return NULL;
622 
623 	param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
624 	return devlink_param_find_by_name(params, param_name);
625 }
626 
627 int devlink_nl_param_get_doit(struct sk_buff *skb,
628 			      struct genl_info *info)
629 {
630 	struct devlink *devlink = info->user_ptr[0];
631 	struct devlink_param_item *param_item;
632 	struct sk_buff *msg;
633 	int err;
634 
635 	param_item = devlink_param_get_from_info(&devlink->params, info);
636 	if (!param_item)
637 		return -EINVAL;
638 
639 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
640 	if (!msg)
641 		return -ENOMEM;
642 
643 	err = devlink_nl_param_fill(msg, devlink, 0, param_item,
644 				    DEVLINK_CMD_PARAM_GET, info->snd_portid,
645 				    info->snd_seq, 0, info->extack);
646 	if (err) {
647 		nlmsg_free(msg);
648 		return err;
649 	}
650 
651 	return genlmsg_reply(msg, info);
652 }
653 
654 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
655 					   unsigned int port_index,
656 					   struct xarray *params,
657 					   struct genl_info *info,
658 					   enum devlink_command cmd)
659 {
660 	enum devlink_param_type param_type;
661 	struct devlink_param_gset_ctx ctx;
662 	enum devlink_param_cmode cmode;
663 	struct devlink_param_item *param_item;
664 	const struct devlink_param *param;
665 	union devlink_param_value value;
666 	bool reset_default;
667 	int err = 0;
668 
669 	param_item = devlink_param_get_from_info(params, info);
670 	if (!param_item)
671 		return -EINVAL;
672 	param = param_item->param;
673 	err = devlink_param_type_get_from_info(info, &param_type);
674 	if (err)
675 		return err;
676 	if (param_type != param->type)
677 		return -EINVAL;
678 
679 	reset_default = info->attrs[DEVLINK_ATTR_PARAM_RESET_DEFAULT];
680 	if (!reset_default) {
681 		err = devlink_param_value_get_from_info(param, info, &value);
682 		if (err)
683 			return err;
684 		if (param->validate) {
685 			err = param->validate(devlink, param->id, &value,
686 					      info->extack);
687 			if (err)
688 				return err;
689 		}
690 	}
691 
692 	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE))
693 		return -EINVAL;
694 	cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
695 	if (!devlink_param_cmode_is_supported(param, cmode))
696 		return -EOPNOTSUPP;
697 
698 	if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
699 		if (reset_default) {
700 			if (!param_item->driverinit_value_valid) {
701 				NL_SET_ERR_MSG(info->extack,
702 					       "Default value not available");
703 				return -EOPNOTSUPP;
704 			}
705 			value = param_item->driverinit_default;
706 		}
707 
708 		param_item->driverinit_value_new = value;
709 		param_item->driverinit_value_new_valid = true;
710 	} else {
711 		if (!param->set)
712 			return -EOPNOTSUPP;
713 		ctx.val = value;
714 		ctx.cmode = cmode;
715 		if (reset_default)
716 			err = devlink_param_reset_default(devlink, param, cmode,
717 							  info->extack);
718 		else
719 			err = devlink_param_set(devlink, param, &ctx,
720 						info->extack);
721 		if (err)
722 			return err;
723 	}
724 
725 	devlink_param_notify(devlink, port_index, param_item, cmd);
726 	return 0;
727 }
728 
729 int devlink_nl_param_set_doit(struct sk_buff *skb, struct genl_info *info)
730 {
731 	struct devlink *devlink = info->user_ptr[0];
732 
733 	return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->params,
734 					       info, DEVLINK_CMD_PARAM_NEW);
735 }
736 
737 int devlink_nl_port_param_get_dumpit(struct sk_buff *msg,
738 				     struct netlink_callback *cb)
739 {
740 	NL_SET_ERR_MSG(cb->extack, "Port params are not supported");
741 	return msg->len;
742 }
743 
744 int devlink_nl_port_param_get_doit(struct sk_buff *skb,
745 				   struct genl_info *info)
746 {
747 	NL_SET_ERR_MSG(info->extack, "Port params are not supported");
748 	return -EINVAL;
749 }
750 
751 int devlink_nl_port_param_set_doit(struct sk_buff *skb,
752 				   struct genl_info *info)
753 {
754 	NL_SET_ERR_MSG(info->extack, "Port params are not supported");
755 	return -EINVAL;
756 }
757 
758 static int devlink_param_verify(const struct devlink_param *param)
759 {
760 	if (!param || !param->name || !param->supported_cmodes)
761 		return -EINVAL;
762 	if (param->generic)
763 		return devlink_param_generic_verify(param);
764 	else
765 		return devlink_param_driver_verify(param);
766 }
767 
768 static int devlink_param_register(struct devlink *devlink,
769 				  const struct devlink_param *param)
770 {
771 	struct devlink_param_item *param_item;
772 	int err;
773 
774 	WARN_ON(devlink_param_verify(param));
775 	WARN_ON(devlink_param_find_by_name(&devlink->params, param->name));
776 
777 	if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
778 		WARN_ON(param->get || param->set);
779 	else
780 		WARN_ON(!param->get || !param->set);
781 
782 	param_item = kzalloc_obj(*param_item);
783 	if (!param_item)
784 		return -ENOMEM;
785 
786 	param_item->param = param;
787 
788 	err = xa_insert(&devlink->params, param->id, param_item, GFP_KERNEL);
789 	if (err)
790 		goto err_xa_insert;
791 
792 	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
793 	return 0;
794 
795 err_xa_insert:
796 	kfree(param_item);
797 	return err;
798 }
799 
800 static void devlink_param_unregister(struct devlink *devlink,
801 				     const struct devlink_param *param)
802 {
803 	struct devlink_param_item *param_item;
804 
805 	param_item = devlink_param_find_by_id(&devlink->params, param->id);
806 	if (WARN_ON(!param_item))
807 		return;
808 	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL);
809 	xa_erase(&devlink->params, param->id);
810 	kfree(param_item);
811 }
812 
813 /**
814  *	devl_params_register - register configuration parameters
815  *
816  *	@devlink: devlink
817  *	@params: configuration parameters array
818  *	@params_count: number of parameters provided
819  *
820  *	Register the configuration parameters supported by the driver.
821  */
822 int devl_params_register(struct devlink *devlink,
823 			 const struct devlink_param *params,
824 			 size_t params_count)
825 {
826 	const struct devlink_param *param = params;
827 	int i, err;
828 
829 	lockdep_assert_held(&devlink->lock);
830 
831 	for (i = 0; i < params_count; i++, param++) {
832 		err = devlink_param_register(devlink, param);
833 		if (err)
834 			goto rollback;
835 	}
836 	return 0;
837 
838 rollback:
839 	if (!i)
840 		return err;
841 
842 	for (param--; i > 0; i--, param--)
843 		devlink_param_unregister(devlink, param);
844 	return err;
845 }
846 EXPORT_SYMBOL_GPL(devl_params_register);
847 
848 int devlink_params_register(struct devlink *devlink,
849 			    const struct devlink_param *params,
850 			    size_t params_count)
851 {
852 	int err;
853 
854 	devl_lock(devlink);
855 	err = devl_params_register(devlink, params, params_count);
856 	devl_unlock(devlink);
857 	return err;
858 }
859 EXPORT_SYMBOL_GPL(devlink_params_register);
860 
861 /**
862  *	devl_params_unregister - unregister configuration parameters
863  *	@devlink: devlink
864  *	@params: configuration parameters to unregister
865  *	@params_count: number of parameters provided
866  */
867 void devl_params_unregister(struct devlink *devlink,
868 			    const struct devlink_param *params,
869 			    size_t params_count)
870 {
871 	const struct devlink_param *param = params;
872 	int i;
873 
874 	lockdep_assert_held(&devlink->lock);
875 
876 	for (i = 0; i < params_count; i++, param++)
877 		devlink_param_unregister(devlink, param);
878 }
879 EXPORT_SYMBOL_GPL(devl_params_unregister);
880 
881 void devlink_params_unregister(struct devlink *devlink,
882 			       const struct devlink_param *params,
883 			       size_t params_count)
884 {
885 	devl_lock(devlink);
886 	devl_params_unregister(devlink, params, params_count);
887 	devl_unlock(devlink);
888 }
889 EXPORT_SYMBOL_GPL(devlink_params_unregister);
890 
891 /**
892  *	devl_param_driverinit_value_get - get configuration parameter
893  *					  value for driver initializing
894  *
895  *	@devlink: devlink
896  *	@param_id: parameter ID
897  *	@val: pointer to store the value of parameter in driverinit
898  *	      configuration mode
899  *
900  *	This function should be used by the driver to get driverinit
901  *	configuration for initialization after reload command.
902  *
903  *	Note that lockless call of this function relies on the
904  *	driver to maintain following basic sane behavior:
905  *	1) Driver ensures a call to this function cannot race with
906  *	   registering/unregistering the parameter with the same parameter ID.
907  *	2) Driver ensures a call to this function cannot race with
908  *	   devl_param_driverinit_value_set() call with the same parameter ID.
909  *	3) Driver ensures a call to this function cannot race with
910  *	   reload operation.
911  *	If the driver is not able to comply, it has to take the devlink->lock
912  *	while calling this.
913  */
914 int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
915 				    union devlink_param_value *val)
916 {
917 	struct devlink_param_item *param_item;
918 
919 	if (WARN_ON(!devlink_reload_supported(devlink->ops)))
920 		return -EOPNOTSUPP;
921 
922 	param_item = devlink_param_find_by_id(&devlink->params, param_id);
923 	if (!param_item)
924 		return -EINVAL;
925 
926 	if (!param_item->driverinit_value_valid)
927 		return -EOPNOTSUPP;
928 
929 	if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
930 						      DEVLINK_PARAM_CMODE_DRIVERINIT)))
931 		return -EOPNOTSUPP;
932 
933 	*val = param_item->driverinit_value;
934 
935 	return 0;
936 }
937 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_get);
938 
939 /**
940  *	devl_param_driverinit_value_set - set value of configuration
941  *					  parameter for driverinit
942  *					  configuration mode
943  *
944  *	@devlink: devlink
945  *	@param_id: parameter ID
946  *	@init_val: value of parameter to set for driverinit configuration mode
947  *
948  *	This function should be used by the driver to set driverinit
949  *	configuration mode default value.
950  */
951 void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
952 				     union devlink_param_value *init_val)
953 {
954 	struct devlink_param_item *param_item;
955 
956 	devl_assert_locked(devlink);
957 
958 	param_item = devlink_param_find_by_id(&devlink->params, param_id);
959 	if (WARN_ON(!param_item))
960 		return;
961 
962 	if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
963 						      DEVLINK_PARAM_CMODE_DRIVERINIT)))
964 		return;
965 
966 	param_item->driverinit_value = *init_val;
967 	param_item->driverinit_value_valid = true;
968 	param_item->driverinit_default = *init_val;
969 
970 	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
971 }
972 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_set);
973 
974 void devlink_params_driverinit_load_new(struct devlink *devlink)
975 {
976 	struct devlink_param_item *param_item;
977 	unsigned long param_id;
978 
979 	xa_for_each(&devlink->params, param_id, param_item) {
980 		if (!devlink_param_cmode_is_supported(param_item->param,
981 						      DEVLINK_PARAM_CMODE_DRIVERINIT) ||
982 		    !param_item->driverinit_value_new_valid)
983 			continue;
984 		param_item->driverinit_value = param_item->driverinit_value_new;
985 		param_item->driverinit_value_valid = true;
986 		param_item->driverinit_value_new_valid = false;
987 	}
988 }
989 
990 /**
991  *	devl_param_value_changed - notify devlink on a parameter's value
992  *				   change. Should be called by the driver
993  *				   right after the change.
994  *
995  *	@devlink: devlink
996  *	@param_id: parameter ID
997  *
998  *	This function should be used by the driver to notify devlink on value
999  *	change, excluding driverinit configuration mode.
1000  *	For driverinit configuration mode driver should use the function
1001  */
1002 void devl_param_value_changed(struct devlink *devlink, u32 param_id)
1003 {
1004 	struct devlink_param_item *param_item;
1005 
1006 	param_item = devlink_param_find_by_id(&devlink->params, param_id);
1007 	WARN_ON(!param_item);
1008 
1009 	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
1010 }
1011 EXPORT_SYMBOL_GPL(devl_param_value_changed);
1012