xref: /openbmc/linux/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c (revision 0af5cb349a2c97fbabb3cede96efcde9d54b7940)
1 /* Broadcom NetXtreme-C/E network driver.
2  *
3  * Copyright (c) 2017 Broadcom Limited
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation.
8  */
9 
10 #include <linux/pci.h>
11 #include <linux/netdevice.h>
12 #include <linux/vmalloc.h>
13 #include <net/devlink.h>
14 #include "bnxt_hsi.h"
15 #include "bnxt.h"
16 #include "bnxt_hwrm.h"
17 #include "bnxt_vfr.h"
18 #include "bnxt_devlink.h"
19 #include "bnxt_ethtool.h"
20 #include "bnxt_ulp.h"
21 #include "bnxt_ptp.h"
22 #include "bnxt_coredump.h"
23 #include "bnxt_nvm_defs.h"
24 #include "bnxt_ethtool.h"
25 
26 static void __bnxt_fw_recover(struct bnxt *bp)
27 {
28 	if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) ||
29 	    test_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state))
30 		bnxt_fw_reset(bp);
31 	else
32 		bnxt_fw_exception(bp);
33 }
34 
35 static int
36 bnxt_dl_flash_update(struct devlink *dl,
37 		     struct devlink_flash_update_params *params,
38 		     struct netlink_ext_ack *extack)
39 {
40 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
41 	int rc;
42 
43 	if (!BNXT_PF(bp)) {
44 		NL_SET_ERR_MSG_MOD(extack,
45 				   "flash update not supported from a VF");
46 		return -EPERM;
47 	}
48 
49 	devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
50 	rc = bnxt_flash_package_from_fw_obj(bp->dev, params->fw, 0, extack);
51 	if (!rc)
52 		devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
53 	else
54 		devlink_flash_update_status_notify(dl, "Flashing failed", NULL, 0, 0);
55 	return rc;
56 }
57 
58 static int bnxt_hwrm_remote_dev_reset_set(struct bnxt *bp, bool remote_reset)
59 {
60 	struct hwrm_func_cfg_input *req;
61 	int rc;
62 
63 	if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
64 		return -EOPNOTSUPP;
65 
66 	rc = hwrm_req_init(bp, req, HWRM_FUNC_CFG);
67 	if (rc)
68 		return rc;
69 
70 	req->fid = cpu_to_le16(0xffff);
71 	req->enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_HOT_RESET_IF_SUPPORT);
72 	if (remote_reset)
73 		req->flags = cpu_to_le32(FUNC_CFG_REQ_FLAGS_HOT_RESET_IF_EN_DIS);
74 
75 	return hwrm_req_send(bp, req);
76 }
77 
78 static char *bnxt_health_severity_str(enum bnxt_health_severity severity)
79 {
80 	switch (severity) {
81 	case SEVERITY_NORMAL: return "normal";
82 	case SEVERITY_WARNING: return "warning";
83 	case SEVERITY_RECOVERABLE: return "recoverable";
84 	case SEVERITY_FATAL: return "fatal";
85 	default: return "unknown";
86 	}
87 }
88 
89 static char *bnxt_health_remedy_str(enum bnxt_health_remedy remedy)
90 {
91 	switch (remedy) {
92 	case REMEDY_DEVLINK_RECOVER: return "devlink recover";
93 	case REMEDY_POWER_CYCLE_DEVICE: return "device power cycle";
94 	case REMEDY_POWER_CYCLE_HOST: return "host power cycle";
95 	case REMEDY_FW_UPDATE: return "update firmware";
96 	case REMEDY_HW_REPLACE: return "replace hardware";
97 	default: return "unknown";
98 	}
99 }
100 
101 static int bnxt_fw_diagnose(struct devlink_health_reporter *reporter,
102 			    struct devlink_fmsg *fmsg,
103 			    struct netlink_ext_ack *extack)
104 {
105 	struct bnxt *bp = devlink_health_reporter_priv(reporter);
106 	struct bnxt_fw_health *h = bp->fw_health;
107 	u32 fw_status, fw_resets;
108 	int rc;
109 
110 	if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
111 		return devlink_fmsg_string_pair_put(fmsg, "Status", "recovering");
112 
113 	if (!h->status_reliable)
114 		return devlink_fmsg_string_pair_put(fmsg, "Status", "unknown");
115 
116 	mutex_lock(&h->lock);
117 	fw_status = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG);
118 	if (BNXT_FW_IS_BOOTING(fw_status)) {
119 		rc = devlink_fmsg_string_pair_put(fmsg, "Status", "initializing");
120 		if (rc)
121 			goto unlock;
122 	} else if (h->severity || fw_status != BNXT_FW_STATUS_HEALTHY) {
123 		if (!h->severity) {
124 			h->severity = SEVERITY_FATAL;
125 			h->remedy = REMEDY_POWER_CYCLE_DEVICE;
126 			h->diagnoses++;
127 			devlink_health_report(h->fw_reporter,
128 					      "FW error diagnosed", h);
129 		}
130 		rc = devlink_fmsg_string_pair_put(fmsg, "Status", "error");
131 		if (rc)
132 			goto unlock;
133 		rc = devlink_fmsg_u32_pair_put(fmsg, "Syndrome", fw_status);
134 		if (rc)
135 			goto unlock;
136 	} else {
137 		rc = devlink_fmsg_string_pair_put(fmsg, "Status", "healthy");
138 		if (rc)
139 			goto unlock;
140 	}
141 
142 	rc = devlink_fmsg_string_pair_put(fmsg, "Severity",
143 					  bnxt_health_severity_str(h->severity));
144 	if (rc)
145 		goto unlock;
146 
147 	if (h->severity) {
148 		rc = devlink_fmsg_string_pair_put(fmsg, "Remedy",
149 						  bnxt_health_remedy_str(h->remedy));
150 		if (rc)
151 			goto unlock;
152 		if (h->remedy == REMEDY_DEVLINK_RECOVER) {
153 			rc = devlink_fmsg_string_pair_put(fmsg, "Impact",
154 							  "traffic+ntuple_cfg");
155 			if (rc)
156 				goto unlock;
157 		}
158 	}
159 
160 unlock:
161 	mutex_unlock(&h->lock);
162 	if (rc || !h->resets_reliable)
163 		return rc;
164 
165 	fw_resets = bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
166 	rc = devlink_fmsg_u32_pair_put(fmsg, "Resets", fw_resets);
167 	if (rc)
168 		return rc;
169 	rc = devlink_fmsg_u32_pair_put(fmsg, "Arrests", h->arrests);
170 	if (rc)
171 		return rc;
172 	rc = devlink_fmsg_u32_pair_put(fmsg, "Survivals", h->survivals);
173 	if (rc)
174 		return rc;
175 	rc = devlink_fmsg_u32_pair_put(fmsg, "Discoveries", h->discoveries);
176 	if (rc)
177 		return rc;
178 	rc = devlink_fmsg_u32_pair_put(fmsg, "Fatalities", h->fatalities);
179 	if (rc)
180 		return rc;
181 	return devlink_fmsg_u32_pair_put(fmsg, "Diagnoses", h->diagnoses);
182 }
183 
184 static int bnxt_fw_dump(struct devlink_health_reporter *reporter,
185 			struct devlink_fmsg *fmsg, void *priv_ctx,
186 			struct netlink_ext_ack *extack)
187 {
188 	struct bnxt *bp = devlink_health_reporter_priv(reporter);
189 	u32 dump_len;
190 	void *data;
191 	int rc;
192 
193 	/* TODO: no firmware dump support in devlink_health_report() context */
194 	if (priv_ctx)
195 		return -EOPNOTSUPP;
196 
197 	dump_len = bnxt_get_coredump_length(bp, BNXT_DUMP_LIVE);
198 	if (!dump_len)
199 		return -EIO;
200 
201 	data = vmalloc(dump_len);
202 	if (!data)
203 		return -ENOMEM;
204 
205 	rc = bnxt_get_coredump(bp, BNXT_DUMP_LIVE, data, &dump_len);
206 	if (!rc) {
207 		rc = devlink_fmsg_pair_nest_start(fmsg, "core");
208 		if (rc)
209 			goto exit;
210 		rc = devlink_fmsg_binary_pair_put(fmsg, "data", data, dump_len);
211 		if (rc)
212 			goto exit;
213 		rc = devlink_fmsg_u32_pair_put(fmsg, "size", dump_len);
214 		if (rc)
215 			goto exit;
216 		rc = devlink_fmsg_pair_nest_end(fmsg);
217 	}
218 
219 exit:
220 	vfree(data);
221 	return rc;
222 }
223 
224 static int bnxt_fw_recover(struct devlink_health_reporter *reporter,
225 			   void *priv_ctx,
226 			   struct netlink_ext_ack *extack)
227 {
228 	struct bnxt *bp = devlink_health_reporter_priv(reporter);
229 
230 	if (bp->fw_health->severity == SEVERITY_FATAL)
231 		return -ENODEV;
232 
233 	set_bit(BNXT_STATE_RECOVER, &bp->state);
234 	__bnxt_fw_recover(bp);
235 
236 	return -EINPROGRESS;
237 }
238 
239 static const struct devlink_health_reporter_ops bnxt_dl_fw_reporter_ops = {
240 	.name = "fw",
241 	.diagnose = bnxt_fw_diagnose,
242 	.dump = bnxt_fw_dump,
243 	.recover = bnxt_fw_recover,
244 };
245 
246 static struct devlink_health_reporter *
247 __bnxt_dl_reporter_create(struct bnxt *bp,
248 			  const struct devlink_health_reporter_ops *ops)
249 {
250 	struct devlink_health_reporter *reporter;
251 
252 	reporter = devlink_health_reporter_create(bp->dl, ops, 0, bp);
253 	if (IS_ERR(reporter)) {
254 		netdev_warn(bp->dev, "Failed to create %s health reporter, rc = %ld\n",
255 			    ops->name, PTR_ERR(reporter));
256 		return NULL;
257 	}
258 
259 	return reporter;
260 }
261 
262 void bnxt_dl_fw_reporters_create(struct bnxt *bp)
263 {
264 	struct bnxt_fw_health *fw_health = bp->fw_health;
265 
266 	if (fw_health && !fw_health->fw_reporter)
267 		fw_health->fw_reporter = __bnxt_dl_reporter_create(bp, &bnxt_dl_fw_reporter_ops);
268 }
269 
270 void bnxt_dl_fw_reporters_destroy(struct bnxt *bp)
271 {
272 	struct bnxt_fw_health *fw_health = bp->fw_health;
273 
274 	if (fw_health && fw_health->fw_reporter) {
275 		devlink_health_reporter_destroy(fw_health->fw_reporter);
276 		fw_health->fw_reporter = NULL;
277 	}
278 }
279 
280 void bnxt_devlink_health_fw_report(struct bnxt *bp)
281 {
282 	struct bnxt_fw_health *fw_health = bp->fw_health;
283 	int rc;
284 
285 	if (!fw_health)
286 		return;
287 
288 	if (!fw_health->fw_reporter) {
289 		__bnxt_fw_recover(bp);
290 		return;
291 	}
292 
293 	mutex_lock(&fw_health->lock);
294 	fw_health->severity = SEVERITY_RECOVERABLE;
295 	fw_health->remedy = REMEDY_DEVLINK_RECOVER;
296 	mutex_unlock(&fw_health->lock);
297 	rc = devlink_health_report(fw_health->fw_reporter, "FW error reported",
298 				   fw_health);
299 	if (rc == -ECANCELED)
300 		__bnxt_fw_recover(bp);
301 }
302 
303 void bnxt_dl_health_fw_status_update(struct bnxt *bp, bool healthy)
304 {
305 	struct bnxt_fw_health *fw_health = bp->fw_health;
306 	u8 state;
307 
308 	mutex_lock(&fw_health->lock);
309 	if (healthy) {
310 		fw_health->severity = SEVERITY_NORMAL;
311 		state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
312 	} else {
313 		fw_health->severity = SEVERITY_FATAL;
314 		fw_health->remedy = REMEDY_POWER_CYCLE_DEVICE;
315 		state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
316 	}
317 	mutex_unlock(&fw_health->lock);
318 	devlink_health_reporter_state_update(fw_health->fw_reporter, state);
319 }
320 
321 void bnxt_dl_health_fw_recovery_done(struct bnxt *bp)
322 {
323 	struct bnxt_dl *dl = devlink_priv(bp->dl);
324 
325 	devlink_health_reporter_recovery_done(bp->fw_health->fw_reporter);
326 	bnxt_hwrm_remote_dev_reset_set(bp, dl->remote_reset);
327 }
328 
329 static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
330 			    struct netlink_ext_ack *extack);
331 
332 static void
333 bnxt_dl_livepatch_report_err(struct bnxt *bp, struct netlink_ext_ack *extack,
334 			     struct hwrm_fw_livepatch_output *resp)
335 {
336 	int err = ((struct hwrm_err_output *)resp)->cmd_err;
337 
338 	switch (err) {
339 	case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_OPCODE:
340 		netdev_err(bp->dev, "Illegal live patch opcode");
341 		NL_SET_ERR_MSG_MOD(extack, "Invalid opcode");
342 		break;
343 	case FW_LIVEPATCH_CMD_ERR_CODE_NOT_SUPPORTED:
344 		NL_SET_ERR_MSG_MOD(extack, "Live patch operation not supported");
345 		break;
346 	case FW_LIVEPATCH_CMD_ERR_CODE_NOT_INSTALLED:
347 		NL_SET_ERR_MSG_MOD(extack, "Live patch not found");
348 		break;
349 	case FW_LIVEPATCH_CMD_ERR_CODE_NOT_PATCHED:
350 		NL_SET_ERR_MSG_MOD(extack,
351 				   "Live patch deactivation failed. Firmware not patched.");
352 		break;
353 	case FW_LIVEPATCH_CMD_ERR_CODE_AUTH_FAIL:
354 		NL_SET_ERR_MSG_MOD(extack, "Live patch not authenticated");
355 		break;
356 	case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_HEADER:
357 		NL_SET_ERR_MSG_MOD(extack, "Incompatible live patch");
358 		break;
359 	case FW_LIVEPATCH_CMD_ERR_CODE_INVALID_SIZE:
360 		NL_SET_ERR_MSG_MOD(extack, "Live patch has invalid size");
361 		break;
362 	case FW_LIVEPATCH_CMD_ERR_CODE_ALREADY_PATCHED:
363 		NL_SET_ERR_MSG_MOD(extack, "Live patch already applied");
364 		break;
365 	default:
366 		netdev_err(bp->dev, "Unexpected live patch error: %d\n", err);
367 		NL_SET_ERR_MSG_MOD(extack, "Failed to activate live patch");
368 		break;
369 	}
370 }
371 
372 /* Live patch status in NVM */
373 #define BNXT_LIVEPATCH_NOT_INSTALLED	0
374 #define BNXT_LIVEPATCH_INSTALLED	FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL
375 #define BNXT_LIVEPATCH_REMOVED		FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE
376 #define BNXT_LIVEPATCH_MASK		(FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL | \
377 					 FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE)
378 #define BNXT_LIVEPATCH_ACTIVATED	BNXT_LIVEPATCH_MASK
379 
380 #define BNXT_LIVEPATCH_STATE(flags)	((flags) & BNXT_LIVEPATCH_MASK)
381 
382 static int
383 bnxt_dl_livepatch_activate(struct bnxt *bp, struct netlink_ext_ack *extack)
384 {
385 	struct hwrm_fw_livepatch_query_output *query_resp;
386 	struct hwrm_fw_livepatch_query_input *query_req;
387 	struct hwrm_fw_livepatch_output *patch_resp;
388 	struct hwrm_fw_livepatch_input *patch_req;
389 	u16 flags, live_patch_state;
390 	bool activated = false;
391 	u32 installed = 0;
392 	u8 target;
393 	int rc;
394 
395 	if (~bp->fw_cap & BNXT_FW_CAP_LIVEPATCH) {
396 		NL_SET_ERR_MSG_MOD(extack, "Device does not support live patch");
397 		return -EOPNOTSUPP;
398 	}
399 
400 	rc = hwrm_req_init(bp, query_req, HWRM_FW_LIVEPATCH_QUERY);
401 	if (rc)
402 		return rc;
403 	query_resp = hwrm_req_hold(bp, query_req);
404 
405 	rc = hwrm_req_init(bp, patch_req, HWRM_FW_LIVEPATCH);
406 	if (rc) {
407 		hwrm_req_drop(bp, query_req);
408 		return rc;
409 	}
410 	patch_req->loadtype = FW_LIVEPATCH_REQ_LOADTYPE_NVM_INSTALL;
411 	patch_resp = hwrm_req_hold(bp, patch_req);
412 
413 	for (target = 1; target <= FW_LIVEPATCH_REQ_FW_TARGET_LAST; target++) {
414 		query_req->fw_target = target;
415 		rc = hwrm_req_send(bp, query_req);
416 		if (rc) {
417 			NL_SET_ERR_MSG_MOD(extack, "Failed to query packages");
418 			break;
419 		}
420 
421 		flags = le16_to_cpu(query_resp->status_flags);
422 		live_patch_state = BNXT_LIVEPATCH_STATE(flags);
423 
424 		if (live_patch_state == BNXT_LIVEPATCH_NOT_INSTALLED)
425 			continue;
426 
427 		if (live_patch_state == BNXT_LIVEPATCH_ACTIVATED) {
428 			activated = true;
429 			continue;
430 		}
431 
432 		if (live_patch_state == BNXT_LIVEPATCH_INSTALLED)
433 			patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_ACTIVATE;
434 		else if (live_patch_state == BNXT_LIVEPATCH_REMOVED)
435 			patch_req->opcode = FW_LIVEPATCH_REQ_OPCODE_DEACTIVATE;
436 
437 		patch_req->fw_target = target;
438 		rc = hwrm_req_send(bp, patch_req);
439 		if (rc) {
440 			bnxt_dl_livepatch_report_err(bp, extack, patch_resp);
441 			break;
442 		}
443 		installed++;
444 	}
445 
446 	if (!rc && !installed) {
447 		if (activated) {
448 			NL_SET_ERR_MSG_MOD(extack, "Live patch already activated");
449 			rc = -EEXIST;
450 		} else {
451 			NL_SET_ERR_MSG_MOD(extack, "No live patches found");
452 			rc = -ENOENT;
453 		}
454 	}
455 	hwrm_req_drop(bp, query_req);
456 	hwrm_req_drop(bp, patch_req);
457 	return rc;
458 }
459 
460 static int bnxt_dl_reload_down(struct devlink *dl, bool netns_change,
461 			       enum devlink_reload_action action,
462 			       enum devlink_reload_limit limit,
463 			       struct netlink_ext_ack *extack)
464 {
465 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
466 	int rc = 0;
467 
468 	switch (action) {
469 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
470 		rtnl_lock();
471 		if (bnxt_sriov_cfg(bp)) {
472 			NL_SET_ERR_MSG_MOD(extack,
473 					   "reload is unsupported while VFs are allocated or being configured");
474 			rtnl_unlock();
475 			return -EOPNOTSUPP;
476 		}
477 		if (bp->dev->reg_state == NETREG_UNREGISTERED) {
478 			rtnl_unlock();
479 			return -ENODEV;
480 		}
481 		bnxt_ulp_stop(bp);
482 		if (netif_running(bp->dev)) {
483 			rc = bnxt_close_nic(bp, true, true);
484 			if (rc) {
485 				NL_SET_ERR_MSG_MOD(extack, "Failed to close");
486 				dev_close(bp->dev);
487 				rtnl_unlock();
488 				break;
489 			}
490 		}
491 		bnxt_vf_reps_free(bp);
492 		rc = bnxt_hwrm_func_drv_unrgtr(bp);
493 		if (rc) {
494 			NL_SET_ERR_MSG_MOD(extack, "Failed to deregister");
495 			if (netif_running(bp->dev))
496 				dev_close(bp->dev);
497 			rtnl_unlock();
498 			break;
499 		}
500 		bnxt_cancel_reservations(bp, false);
501 		bnxt_free_ctx_mem(bp);
502 		kfree(bp->ctx);
503 		bp->ctx = NULL;
504 		break;
505 	}
506 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: {
507 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
508 			return bnxt_dl_livepatch_activate(bp, extack);
509 		if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET) {
510 			NL_SET_ERR_MSG_MOD(extack, "Device not capable, requires reboot");
511 			return -EOPNOTSUPP;
512 		}
513 		if (!bnxt_hwrm_reset_permitted(bp)) {
514 			NL_SET_ERR_MSG_MOD(extack,
515 					   "Reset denied by firmware, it may be inhibited by remote driver");
516 			return -EPERM;
517 		}
518 		rtnl_lock();
519 		if (bp->dev->reg_state == NETREG_UNREGISTERED) {
520 			rtnl_unlock();
521 			return -ENODEV;
522 		}
523 		if (netif_running(bp->dev))
524 			set_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
525 		rc = bnxt_hwrm_firmware_reset(bp->dev,
526 					      FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP,
527 					      FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP,
528 					      FW_RESET_REQ_FLAGS_RESET_GRACEFUL |
529 					      FW_RESET_REQ_FLAGS_FW_ACTIVATION);
530 		if (rc) {
531 			NL_SET_ERR_MSG_MOD(extack, "Failed to activate firmware");
532 			clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
533 			rtnl_unlock();
534 		}
535 		break;
536 	}
537 	default:
538 		rc = -EOPNOTSUPP;
539 	}
540 
541 	return rc;
542 }
543 
544 static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action action,
545 			     enum devlink_reload_limit limit, u32 *actions_performed,
546 			     struct netlink_ext_ack *extack)
547 {
548 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
549 	int rc = 0;
550 
551 	*actions_performed = 0;
552 	switch (action) {
553 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT: {
554 		bnxt_fw_init_one(bp);
555 		bnxt_vf_reps_alloc(bp);
556 		if (netif_running(bp->dev))
557 			rc = bnxt_open_nic(bp, true, true);
558 		bnxt_ulp_start(bp, rc);
559 		if (!rc) {
560 			bnxt_reenable_sriov(bp);
561 			bnxt_ptp_reapply_pps(bp);
562 		}
563 		break;
564 	}
565 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE: {
566 		unsigned long start = jiffies;
567 		unsigned long timeout = start + BNXT_DFLT_FW_RST_MAX_DSECS * HZ / 10;
568 
569 		if (limit == DEVLINK_RELOAD_LIMIT_NO_RESET)
570 			break;
571 		if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)
572 			timeout = start + bp->fw_health->normal_func_wait_dsecs * HZ / 10;
573 		if (!netif_running(bp->dev))
574 			NL_SET_ERR_MSG_MOD(extack,
575 					   "Device is closed, not waiting for reset notice that will never come");
576 		rtnl_unlock();
577 		while (test_bit(BNXT_STATE_FW_ACTIVATE, &bp->state)) {
578 			if (time_after(jiffies, timeout)) {
579 				NL_SET_ERR_MSG_MOD(extack, "Activation incomplete");
580 				rc = -ETIMEDOUT;
581 				break;
582 			}
583 			if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) {
584 				NL_SET_ERR_MSG_MOD(extack, "Activation aborted");
585 				rc = -ENODEV;
586 				break;
587 			}
588 			msleep(50);
589 		}
590 		rtnl_lock();
591 		if (!rc)
592 			*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
593 		clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state);
594 		break;
595 	}
596 	default:
597 		return -EOPNOTSUPP;
598 	}
599 
600 	if (!rc) {
601 		bnxt_print_device_info(bp);
602 		if (netif_running(bp->dev)) {
603 			mutex_lock(&bp->link_lock);
604 			bnxt_report_link(bp);
605 			mutex_unlock(&bp->link_lock);
606 		}
607 		*actions_performed |= BIT(action);
608 	} else if (netif_running(bp->dev)) {
609 		dev_close(bp->dev);
610 	}
611 	rtnl_unlock();
612 	return rc;
613 }
614 
615 static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
616 {
617 	u32 datalen;
618 	u16 index;
619 	u8 *buf;
620 
621 	if (bnxt_find_nvram_item(bp->dev, BNX_DIR_TYPE_VPD,
622 				 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
623 				 &index, NULL, &datalen) || !datalen) {
624 		NL_SET_ERR_MSG_MOD(extack, "nvm test vpd entry error");
625 		return false;
626 	}
627 
628 	buf = kzalloc(datalen, GFP_KERNEL);
629 	if (!buf) {
630 		NL_SET_ERR_MSG_MOD(extack, "insufficient memory for nvm test");
631 		return false;
632 	}
633 
634 	if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) {
635 		NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error");
636 		goto err;
637 	}
638 
639 	if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST,
640 			     BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) {
641 		NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error");
642 		goto err;
643 	}
644 
645 	return true;
646 
647 err:
648 	kfree(buf);
649 	return false;
650 }
651 
652 static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id,
653 				   struct netlink_ext_ack *extack)
654 {
655 	return id == DEVLINK_ATTR_SELFTEST_ID_FLASH;
656 }
657 
658 static enum devlink_selftest_status bnxt_dl_selftest_run(struct devlink *dl,
659 							 unsigned int id,
660 							 struct netlink_ext_ack *extack)
661 {
662 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
663 
664 	if (id == DEVLINK_ATTR_SELFTEST_ID_FLASH)
665 		return bnxt_nvm_test(bp, extack) ?
666 				DEVLINK_SELFTEST_STATUS_PASS :
667 				DEVLINK_SELFTEST_STATUS_FAIL;
668 
669 	return DEVLINK_SELFTEST_STATUS_SKIP;
670 }
671 
672 static const struct devlink_ops bnxt_dl_ops = {
673 #ifdef CONFIG_BNXT_SRIOV
674 	.eswitch_mode_set = bnxt_dl_eswitch_mode_set,
675 	.eswitch_mode_get = bnxt_dl_eswitch_mode_get,
676 #endif /* CONFIG_BNXT_SRIOV */
677 	.info_get	  = bnxt_dl_info_get,
678 	.flash_update	  = bnxt_dl_flash_update,
679 	.reload_actions	  = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
680 			    BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
681 	.reload_limits	  = BIT(DEVLINK_RELOAD_LIMIT_NO_RESET),
682 	.reload_down	  = bnxt_dl_reload_down,
683 	.reload_up	  = bnxt_dl_reload_up,
684 	.selftest_check	  = bnxt_dl_selftest_check,
685 	.selftest_run	  = bnxt_dl_selftest_run,
686 };
687 
688 static const struct devlink_ops bnxt_vf_dl_ops;
689 
690 enum bnxt_dl_param_id {
691 	BNXT_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
692 	BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK,
693 };
694 
695 static const struct bnxt_dl_nvm_param nvm_params[] = {
696 	{DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, NVM_OFF_ENABLE_SRIOV,
697 	 BNXT_NVM_SHARED_CFG, 1, 1},
698 	{DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI, NVM_OFF_IGNORE_ARI,
699 	 BNXT_NVM_SHARED_CFG, 1, 1},
700 	{DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
701 	 NVM_OFF_MSIX_VEC_PER_PF_MAX, BNXT_NVM_SHARED_CFG, 10, 4},
702 	{DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
703 	 NVM_OFF_MSIX_VEC_PER_PF_MIN, BNXT_NVM_SHARED_CFG, 7, 4},
704 	{BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK, NVM_OFF_DIS_GRE_VER_CHECK,
705 	 BNXT_NVM_SHARED_CFG, 1, 1},
706 };
707 
708 union bnxt_nvm_data {
709 	u8	val8;
710 	__le32	val32;
711 };
712 
713 static void bnxt_copy_to_nvm_data(union bnxt_nvm_data *dst,
714 				  union devlink_param_value *src,
715 				  int nvm_num_bits, int dl_num_bytes)
716 {
717 	u32 val32 = 0;
718 
719 	if (nvm_num_bits == 1) {
720 		dst->val8 = src->vbool;
721 		return;
722 	}
723 	if (dl_num_bytes == 4)
724 		val32 = src->vu32;
725 	else if (dl_num_bytes == 2)
726 		val32 = (u32)src->vu16;
727 	else if (dl_num_bytes == 1)
728 		val32 = (u32)src->vu8;
729 	dst->val32 = cpu_to_le32(val32);
730 }
731 
732 static void bnxt_copy_from_nvm_data(union devlink_param_value *dst,
733 				    union bnxt_nvm_data *src,
734 				    int nvm_num_bits, int dl_num_bytes)
735 {
736 	u32 val32;
737 
738 	if (nvm_num_bits == 1) {
739 		dst->vbool = src->val8;
740 		return;
741 	}
742 	val32 = le32_to_cpu(src->val32);
743 	if (dl_num_bytes == 4)
744 		dst->vu32 = val32;
745 	else if (dl_num_bytes == 2)
746 		dst->vu16 = (u16)val32;
747 	else if (dl_num_bytes == 1)
748 		dst->vu8 = (u8)val32;
749 }
750 
751 static int bnxt_hwrm_get_nvm_cfg_ver(struct bnxt *bp, u32 *nvm_cfg_ver)
752 {
753 	struct hwrm_nvm_get_variable_input *req;
754 	u16 bytes = BNXT_NVM_CFG_VER_BYTES;
755 	u16 bits = BNXT_NVM_CFG_VER_BITS;
756 	union devlink_param_value ver;
757 	union bnxt_nvm_data *data;
758 	dma_addr_t data_dma_addr;
759 	int rc, i = 2;
760 	u16 dim = 1;
761 
762 	rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
763 	if (rc)
764 		return rc;
765 
766 	data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr);
767 	if (!data) {
768 		rc = -ENOMEM;
769 		goto exit;
770 	}
771 
772 	/* earlier devices present as an array of raw bytes */
773 	if (!BNXT_CHIP_P5(bp)) {
774 		dim = 0;
775 		i = 0;
776 		bits *= 3;  /* array of 3 version components */
777 		bytes *= 4; /* copy whole word */
778 	}
779 
780 	hwrm_req_hold(bp, req);
781 	req->dest_data_addr = cpu_to_le64(data_dma_addr);
782 	req->data_len = cpu_to_le16(bits);
783 	req->option_num = cpu_to_le16(NVM_OFF_NVM_CFG_VER);
784 	req->dimensions = cpu_to_le16(dim);
785 
786 	while (i >= 0) {
787 		req->index_0 = cpu_to_le16(i--);
788 		rc = hwrm_req_send_silent(bp, req);
789 		if (rc)
790 			goto exit;
791 		bnxt_copy_from_nvm_data(&ver, data, bits, bytes);
792 
793 		if (BNXT_CHIP_P5(bp)) {
794 			*nvm_cfg_ver <<= 8;
795 			*nvm_cfg_ver |= ver.vu8;
796 		} else {
797 			*nvm_cfg_ver = ver.vu32;
798 		}
799 	}
800 
801 exit:
802 	hwrm_req_drop(bp, req);
803 	return rc;
804 }
805 
806 static int bnxt_dl_info_put(struct bnxt *bp, struct devlink_info_req *req,
807 			    enum bnxt_dl_version_type type, const char *key,
808 			    char *buf)
809 {
810 	if (!strlen(buf))
811 		return 0;
812 
813 	if ((bp->flags & BNXT_FLAG_CHIP_P5) &&
814 	    (!strcmp(key, DEVLINK_INFO_VERSION_GENERIC_FW_NCSI) ||
815 	     !strcmp(key, DEVLINK_INFO_VERSION_GENERIC_FW_ROCE)))
816 		return 0;
817 
818 	switch (type) {
819 	case BNXT_VERSION_FIXED:
820 		return devlink_info_version_fixed_put(req, key, buf);
821 	case BNXT_VERSION_RUNNING:
822 		return devlink_info_version_running_put(req, key, buf);
823 	case BNXT_VERSION_STORED:
824 		return devlink_info_version_stored_put(req, key, buf);
825 	}
826 	return 0;
827 }
828 
829 #define BNXT_FW_SRT_PATCH	"fw.srt.patch"
830 #define BNXT_FW_CRT_PATCH	"fw.crt.patch"
831 
832 static int bnxt_dl_livepatch_info_put(struct bnxt *bp,
833 				      struct devlink_info_req *req,
834 				      const char *key)
835 {
836 	struct hwrm_fw_livepatch_query_input *query;
837 	struct hwrm_fw_livepatch_query_output *resp;
838 	u16 flags;
839 	int rc;
840 
841 	if (~bp->fw_cap & BNXT_FW_CAP_LIVEPATCH)
842 		return 0;
843 
844 	rc = hwrm_req_init(bp, query, HWRM_FW_LIVEPATCH_QUERY);
845 	if (rc)
846 		return rc;
847 
848 	if (!strcmp(key, BNXT_FW_SRT_PATCH))
849 		query->fw_target = FW_LIVEPATCH_QUERY_REQ_FW_TARGET_SECURE_FW;
850 	else if (!strcmp(key, BNXT_FW_CRT_PATCH))
851 		query->fw_target = FW_LIVEPATCH_QUERY_REQ_FW_TARGET_COMMON_FW;
852 	else
853 		goto exit;
854 
855 	resp = hwrm_req_hold(bp, query);
856 	rc = hwrm_req_send(bp, query);
857 	if (rc)
858 		goto exit;
859 
860 	flags = le16_to_cpu(resp->status_flags);
861 	if (flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_ACTIVE) {
862 		resp->active_ver[sizeof(resp->active_ver) - 1] = '\0';
863 		rc = devlink_info_version_running_put(req, key, resp->active_ver);
864 		if (rc)
865 			goto exit;
866 	}
867 
868 	if (flags & FW_LIVEPATCH_QUERY_RESP_STATUS_FLAGS_INSTALL) {
869 		resp->install_ver[sizeof(resp->install_ver) - 1] = '\0';
870 		rc = devlink_info_version_stored_put(req, key, resp->install_ver);
871 		if (rc)
872 			goto exit;
873 	}
874 
875 exit:
876 	hwrm_req_drop(bp, query);
877 	return rc;
878 }
879 
880 #define HWRM_FW_VER_STR_LEN	16
881 
882 static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
883 			    struct netlink_ext_ack *extack)
884 {
885 	struct hwrm_nvm_get_dev_info_output nvm_dev_info;
886 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
887 	struct hwrm_ver_get_output *ver_resp;
888 	char mgmt_ver[FW_VER_STR_LEN];
889 	char roce_ver[FW_VER_STR_LEN];
890 	char ncsi_ver[FW_VER_STR_LEN];
891 	char buf[32];
892 	u32 ver = 0;
893 	int rc;
894 
895 	rc = devlink_info_driver_name_put(req, DRV_MODULE_NAME);
896 	if (rc)
897 		return rc;
898 
899 	if (BNXT_PF(bp) && (bp->flags & BNXT_FLAG_DSN_VALID)) {
900 		sprintf(buf, "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X",
901 			bp->dsn[7], bp->dsn[6], bp->dsn[5], bp->dsn[4],
902 			bp->dsn[3], bp->dsn[2], bp->dsn[1], bp->dsn[0]);
903 		rc = devlink_info_serial_number_put(req, buf);
904 		if (rc)
905 			return rc;
906 	}
907 
908 	if (strlen(bp->board_serialno)) {
909 		rc = devlink_info_board_serial_number_put(req, bp->board_serialno);
910 		if (rc)
911 			return rc;
912 	}
913 
914 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED,
915 			      DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
916 			      bp->board_partno);
917 	if (rc)
918 		return rc;
919 
920 	sprintf(buf, "%X", bp->chip_num);
921 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED,
922 			      DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, buf);
923 	if (rc)
924 		return rc;
925 
926 	ver_resp = &bp->ver_resp;
927 	sprintf(buf, "%c%d", 'A' + ver_resp->chip_rev, ver_resp->chip_metal);
928 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_FIXED,
929 			      DEVLINK_INFO_VERSION_GENERIC_ASIC_REV, buf);
930 	if (rc)
931 		return rc;
932 
933 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
934 			      DEVLINK_INFO_VERSION_GENERIC_FW_PSID,
935 			      bp->nvm_cfg_ver);
936 	if (rc)
937 		return rc;
938 
939 	buf[0] = 0;
940 	strncat(buf, ver_resp->active_pkg_name, HWRM_FW_VER_STR_LEN);
941 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
942 			      DEVLINK_INFO_VERSION_GENERIC_FW, buf);
943 	if (rc)
944 		return rc;
945 
946 	if (BNXT_PF(bp) && !bnxt_hwrm_get_nvm_cfg_ver(bp, &ver)) {
947 		sprintf(buf, "%d.%d.%d", (ver >> 16) & 0xff, (ver >> 8) & 0xff,
948 			ver & 0xff);
949 		rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
950 				      DEVLINK_INFO_VERSION_GENERIC_FW_PSID,
951 				      buf);
952 		if (rc)
953 			return rc;
954 	}
955 
956 	if (ver_resp->flags & VER_GET_RESP_FLAGS_EXT_VER_AVAIL) {
957 		snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
958 			 ver_resp->hwrm_fw_major, ver_resp->hwrm_fw_minor,
959 			 ver_resp->hwrm_fw_build, ver_resp->hwrm_fw_patch);
960 
961 		snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
962 			 ver_resp->mgmt_fw_major, ver_resp->mgmt_fw_minor,
963 			 ver_resp->mgmt_fw_build, ver_resp->mgmt_fw_patch);
964 
965 		snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
966 			 ver_resp->roce_fw_major, ver_resp->roce_fw_minor,
967 			 ver_resp->roce_fw_build, ver_resp->roce_fw_patch);
968 	} else {
969 		snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
970 			 ver_resp->hwrm_fw_maj_8b, ver_resp->hwrm_fw_min_8b,
971 			 ver_resp->hwrm_fw_bld_8b, ver_resp->hwrm_fw_rsvd_8b);
972 
973 		snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
974 			 ver_resp->mgmt_fw_maj_8b, ver_resp->mgmt_fw_min_8b,
975 			 ver_resp->mgmt_fw_bld_8b, ver_resp->mgmt_fw_rsvd_8b);
976 
977 		snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
978 			 ver_resp->roce_fw_maj_8b, ver_resp->roce_fw_min_8b,
979 			 ver_resp->roce_fw_bld_8b, ver_resp->roce_fw_rsvd_8b);
980 	}
981 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
982 			      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver);
983 	if (rc)
984 		return rc;
985 
986 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
987 			      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
988 			      bp->hwrm_ver_supp);
989 	if (rc)
990 		return rc;
991 
992 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
993 			      DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, ncsi_ver);
994 	if (rc)
995 		return rc;
996 
997 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_RUNNING,
998 			      DEVLINK_INFO_VERSION_GENERIC_FW_ROCE, roce_ver);
999 	if (rc)
1000 		return rc;
1001 
1002 	rc = bnxt_hwrm_nvm_get_dev_info(bp, &nvm_dev_info);
1003 	if (rc ||
1004 	    !(nvm_dev_info.flags & NVM_GET_DEV_INFO_RESP_FLAGS_FW_VER_VALID)) {
1005 		if (!bnxt_get_pkginfo(bp->dev, buf, sizeof(buf)))
1006 			return bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1007 						DEVLINK_INFO_VERSION_GENERIC_FW,
1008 						buf);
1009 		return 0;
1010 	}
1011 
1012 	buf[0] = 0;
1013 	strncat(buf, nvm_dev_info.pkg_name, HWRM_FW_VER_STR_LEN);
1014 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1015 			      DEVLINK_INFO_VERSION_GENERIC_FW, buf);
1016 	if (rc)
1017 		return rc;
1018 
1019 	snprintf(mgmt_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
1020 		 nvm_dev_info.hwrm_fw_major, nvm_dev_info.hwrm_fw_minor,
1021 		 nvm_dev_info.hwrm_fw_build, nvm_dev_info.hwrm_fw_patch);
1022 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1023 			      DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver);
1024 	if (rc)
1025 		return rc;
1026 
1027 	snprintf(ncsi_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
1028 		 nvm_dev_info.mgmt_fw_major, nvm_dev_info.mgmt_fw_minor,
1029 		 nvm_dev_info.mgmt_fw_build, nvm_dev_info.mgmt_fw_patch);
1030 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1031 			      DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, ncsi_ver);
1032 	if (rc)
1033 		return rc;
1034 
1035 	snprintf(roce_ver, FW_VER_STR_LEN, "%d.%d.%d.%d",
1036 		 nvm_dev_info.roce_fw_major, nvm_dev_info.roce_fw_minor,
1037 		 nvm_dev_info.roce_fw_build, nvm_dev_info.roce_fw_patch);
1038 	rc = bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
1039 			      DEVLINK_INFO_VERSION_GENERIC_FW_ROCE, roce_ver);
1040 	if (rc)
1041 		return rc;
1042 
1043 	if (BNXT_CHIP_P5(bp)) {
1044 		rc = bnxt_dl_livepatch_info_put(bp, req, BNXT_FW_SRT_PATCH);
1045 		if (rc)
1046 			return rc;
1047 	}
1048 	return bnxt_dl_livepatch_info_put(bp, req, BNXT_FW_CRT_PATCH);
1049 
1050 }
1051 
1052 static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
1053 			     union devlink_param_value *val)
1054 {
1055 	struct hwrm_nvm_get_variable_input *req = msg;
1056 	struct bnxt_dl_nvm_param nvm_param;
1057 	struct hwrm_err_output *resp;
1058 	union bnxt_nvm_data *data;
1059 	dma_addr_t data_dma_addr;
1060 	int idx = 0, rc, i;
1061 
1062 	/* Get/Set NVM CFG parameter is supported only on PFs */
1063 	if (BNXT_VF(bp)) {
1064 		hwrm_req_drop(bp, req);
1065 		return -EPERM;
1066 	}
1067 
1068 	for (i = 0; i < ARRAY_SIZE(nvm_params); i++) {
1069 		if (nvm_params[i].id == param_id) {
1070 			nvm_param = nvm_params[i];
1071 			break;
1072 		}
1073 	}
1074 
1075 	if (i == ARRAY_SIZE(nvm_params)) {
1076 		hwrm_req_drop(bp, req);
1077 		return -EOPNOTSUPP;
1078 	}
1079 
1080 	if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
1081 		idx = bp->pf.port_id;
1082 	else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG)
1083 		idx = bp->pf.fw_fid - BNXT_FIRST_PF_FID;
1084 
1085 	data = hwrm_req_dma_slice(bp, req, sizeof(*data), &data_dma_addr);
1086 
1087 	if (!data) {
1088 		hwrm_req_drop(bp, req);
1089 		return -ENOMEM;
1090 	}
1091 
1092 	req->dest_data_addr = cpu_to_le64(data_dma_addr);
1093 	req->data_len = cpu_to_le16(nvm_param.nvm_num_bits);
1094 	req->option_num = cpu_to_le16(nvm_param.offset);
1095 	req->index_0 = cpu_to_le16(idx);
1096 	if (idx)
1097 		req->dimensions = cpu_to_le16(1);
1098 
1099 	resp = hwrm_req_hold(bp, req);
1100 	if (req->req_type == cpu_to_le16(HWRM_NVM_SET_VARIABLE)) {
1101 		bnxt_copy_to_nvm_data(data, val, nvm_param.nvm_num_bits,
1102 				      nvm_param.dl_num_bytes);
1103 		rc = hwrm_req_send(bp, msg);
1104 	} else {
1105 		rc = hwrm_req_send_silent(bp, msg);
1106 		if (!rc) {
1107 			bnxt_copy_from_nvm_data(val, data,
1108 						nvm_param.nvm_num_bits,
1109 						nvm_param.dl_num_bytes);
1110 		} else {
1111 			if (resp->cmd_err ==
1112 				NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST)
1113 				rc = -EOPNOTSUPP;
1114 		}
1115 	}
1116 	hwrm_req_drop(bp, req);
1117 	if (rc == -EACCES)
1118 		netdev_err(bp->dev, "PF does not have admin privileges to modify NVM config\n");
1119 	return rc;
1120 }
1121 
1122 static int bnxt_dl_nvm_param_get(struct devlink *dl, u32 id,
1123 				 struct devlink_param_gset_ctx *ctx)
1124 {
1125 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
1126 	struct hwrm_nvm_get_variable_input *req;
1127 	int rc;
1128 
1129 	rc = hwrm_req_init(bp, req, HWRM_NVM_GET_VARIABLE);
1130 	if (rc)
1131 		return rc;
1132 
1133 	rc = bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
1134 	if (!rc && id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
1135 		ctx->val.vbool = !ctx->val.vbool;
1136 
1137 	return rc;
1138 }
1139 
1140 static int bnxt_dl_nvm_param_set(struct devlink *dl, u32 id,
1141 				 struct devlink_param_gset_ctx *ctx)
1142 {
1143 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
1144 	struct hwrm_nvm_set_variable_input *req;
1145 	int rc;
1146 
1147 	rc = hwrm_req_init(bp, req, HWRM_NVM_SET_VARIABLE);
1148 	if (rc)
1149 		return rc;
1150 
1151 	if (id == BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK)
1152 		ctx->val.vbool = !ctx->val.vbool;
1153 
1154 	return bnxt_hwrm_nvm_req(bp, id, req, &ctx->val);
1155 }
1156 
1157 static int bnxt_dl_msix_validate(struct devlink *dl, u32 id,
1158 				 union devlink_param_value val,
1159 				 struct netlink_ext_ack *extack)
1160 {
1161 	int max_val = -1;
1162 
1163 	if (id == DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX)
1164 		max_val = BNXT_MSIX_VEC_MAX;
1165 
1166 	if (id == DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN)
1167 		max_val = BNXT_MSIX_VEC_MIN_MAX;
1168 
1169 	if (val.vu32 > max_val) {
1170 		NL_SET_ERR_MSG_MOD(extack, "MSIX value is exceeding the range");
1171 		return -EINVAL;
1172 	}
1173 
1174 	return 0;
1175 }
1176 
1177 static int bnxt_remote_dev_reset_get(struct devlink *dl, u32 id,
1178 				     struct devlink_param_gset_ctx *ctx)
1179 {
1180 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
1181 
1182 	if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
1183 		return -EOPNOTSUPP;
1184 
1185 	ctx->val.vbool = bnxt_dl_get_remote_reset(dl);
1186 	return 0;
1187 }
1188 
1189 static int bnxt_remote_dev_reset_set(struct devlink *dl, u32 id,
1190 				     struct devlink_param_gset_ctx *ctx)
1191 {
1192 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
1193 	int rc;
1194 
1195 	rc = bnxt_hwrm_remote_dev_reset_set(bp, ctx->val.vbool);
1196 	if (rc)
1197 		return rc;
1198 
1199 	bnxt_dl_set_remote_reset(dl, ctx->val.vbool);
1200 	return rc;
1201 }
1202 
1203 static const struct devlink_param bnxt_dl_params[] = {
1204 	DEVLINK_PARAM_GENERIC(ENABLE_SRIOV,
1205 			      BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1206 			      bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1207 			      NULL),
1208 	DEVLINK_PARAM_GENERIC(IGNORE_ARI,
1209 			      BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1210 			      bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1211 			      NULL),
1212 	DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MAX,
1213 			      BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1214 			      bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1215 			      bnxt_dl_msix_validate),
1216 	DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MIN,
1217 			      BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1218 			      bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1219 			      bnxt_dl_msix_validate),
1220 	DEVLINK_PARAM_DRIVER(BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK,
1221 			     "gre_ver_check", DEVLINK_PARAM_TYPE_BOOL,
1222 			     BIT(DEVLINK_PARAM_CMODE_PERMANENT),
1223 			     bnxt_dl_nvm_param_get, bnxt_dl_nvm_param_set,
1224 			     NULL),
1225 	/* keep REMOTE_DEV_RESET last, it is excluded based on caps */
1226 	DEVLINK_PARAM_GENERIC(ENABLE_REMOTE_DEV_RESET,
1227 			      BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1228 			      bnxt_remote_dev_reset_get,
1229 			      bnxt_remote_dev_reset_set, NULL),
1230 };
1231 
1232 static int bnxt_dl_params_register(struct bnxt *bp)
1233 {
1234 	int num_params = ARRAY_SIZE(bnxt_dl_params);
1235 	int rc;
1236 
1237 	if (bp->hwrm_spec_code < 0x10600)
1238 		return 0;
1239 
1240 	if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
1241 		num_params--;
1242 
1243 	rc = devlink_params_register(bp->dl, bnxt_dl_params, num_params);
1244 	if (rc)
1245 		netdev_warn(bp->dev, "devlink_params_register failed. rc=%d\n",
1246 			    rc);
1247 	return rc;
1248 }
1249 
1250 static void bnxt_dl_params_unregister(struct bnxt *bp)
1251 {
1252 	int num_params = ARRAY_SIZE(bnxt_dl_params);
1253 
1254 	if (bp->hwrm_spec_code < 0x10600)
1255 		return;
1256 
1257 	if (~bp->fw_cap & BNXT_FW_CAP_HOT_RESET_IF)
1258 		num_params--;
1259 
1260 	devlink_params_unregister(bp->dl, bnxt_dl_params, num_params);
1261 }
1262 
1263 int bnxt_dl_register(struct bnxt *bp)
1264 {
1265 	const struct devlink_ops *devlink_ops;
1266 	struct devlink_port_attrs attrs = {};
1267 	struct bnxt_dl *bp_dl;
1268 	struct devlink *dl;
1269 	int rc;
1270 
1271 	if (BNXT_PF(bp))
1272 		devlink_ops = &bnxt_dl_ops;
1273 	else
1274 		devlink_ops = &bnxt_vf_dl_ops;
1275 
1276 	dl = devlink_alloc(devlink_ops, sizeof(struct bnxt_dl), &bp->pdev->dev);
1277 	if (!dl) {
1278 		netdev_warn(bp->dev, "devlink_alloc failed\n");
1279 		return -ENOMEM;
1280 	}
1281 
1282 	bp->dl = dl;
1283 	bp_dl = devlink_priv(dl);
1284 	bp_dl->bp = bp;
1285 	bnxt_dl_set_remote_reset(dl, true);
1286 
1287 	/* Add switchdev eswitch mode setting, if SRIOV supported */
1288 	if (pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV) &&
1289 	    bp->hwrm_spec_code > 0x10803)
1290 		bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY;
1291 
1292 	if (!BNXT_PF(bp))
1293 		goto out;
1294 
1295 	attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
1296 	attrs.phys.port_number = bp->pf.port_id;
1297 	memcpy(attrs.switch_id.id, bp->dsn, sizeof(bp->dsn));
1298 	attrs.switch_id.id_len = sizeof(bp->dsn);
1299 	devlink_port_attrs_set(&bp->dl_port, &attrs);
1300 	rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id);
1301 	if (rc) {
1302 		netdev_err(bp->dev, "devlink_port_register failed\n");
1303 		goto err_dl_free;
1304 	}
1305 
1306 	rc = bnxt_dl_params_register(bp);
1307 	if (rc)
1308 		goto err_dl_port_unreg;
1309 
1310 out:
1311 	devlink_register(dl);
1312 	return 0;
1313 
1314 err_dl_port_unreg:
1315 	devlink_port_unregister(&bp->dl_port);
1316 err_dl_free:
1317 	devlink_free(dl);
1318 	return rc;
1319 }
1320 
1321 void bnxt_dl_unregister(struct bnxt *bp)
1322 {
1323 	struct devlink *dl = bp->dl;
1324 
1325 	devlink_unregister(dl);
1326 	if (BNXT_PF(bp)) {
1327 		bnxt_dl_params_unregister(bp);
1328 		devlink_port_unregister(&bp->dl_port);
1329 	}
1330 	devlink_free(dl);
1331 }
1332