1 /* Broadcom NetXtreme-C/E network driver.
3 * Copyright (c) 2017 Broadcom Limited
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.
10 #include <linux/pci.h>
11 #include <linux/netdevice.h>
12 #include <net/devlink.h>
16 #include "bnxt_devlink.h"
17 #include "bnxt_ethtool.h"
20 bnxt_dl_flash_update(struct devlink
*dl
,
21 struct devlink_flash_update_params
*params
,
22 struct netlink_ext_ack
*extack
)
24 struct bnxt
*bp
= bnxt_get_bp_from_dl(dl
);
28 NL_SET_ERR_MSG_MOD(extack
,
29 "flash update not supported from a VF");
33 devlink_flash_update_status_notify(dl
, "Preparing to flash", NULL
, 0, 0);
34 rc
= bnxt_flash_package_from_fw_obj(bp
->dev
, params
->fw
, 0);
36 devlink_flash_update_status_notify(dl
, "Flashing done", NULL
, 0, 0);
38 devlink_flash_update_status_notify(dl
, "Flashing failed", NULL
, 0, 0);
42 static int bnxt_fw_reporter_diagnose(struct devlink_health_reporter
*reporter
,
43 struct devlink_fmsg
*fmsg
,
44 struct netlink_ext_ack
*extack
)
46 struct bnxt
*bp
= devlink_health_reporter_priv(reporter
);
47 u32 val
, health_status
;
50 if (test_bit(BNXT_STATE_IN_FW_RESET
, &bp
->state
))
53 val
= bnxt_fw_health_readl(bp
, BNXT_FW_HEALTH_REG
);
54 health_status
= val
& 0xffff;
56 if (health_status
< BNXT_FW_STATUS_HEALTHY
) {
57 rc
= devlink_fmsg_string_pair_put(fmsg
, "Description",
58 "Not yet completed initialization");
61 } else if (health_status
> BNXT_FW_STATUS_HEALTHY
) {
62 rc
= devlink_fmsg_string_pair_put(fmsg
, "Description",
63 "Encountered fatal error and cannot recover");
69 rc
= devlink_fmsg_u32_pair_put(fmsg
, "Error code", val
>> 16);
74 val
= bnxt_fw_health_readl(bp
, BNXT_FW_RESET_CNT_REG
);
75 rc
= devlink_fmsg_u32_pair_put(fmsg
, "Reset count", val
);
82 static const struct devlink_health_reporter_ops bnxt_dl_fw_reporter_ops
= {
84 .diagnose
= bnxt_fw_reporter_diagnose
,
87 static int bnxt_fw_reset_recover(struct devlink_health_reporter
*reporter
,
89 struct netlink_ext_ack
*extack
)
91 struct bnxt
*bp
= devlink_health_reporter_priv(reporter
);
101 struct devlink_health_reporter_ops bnxt_dl_fw_reset_reporter_ops
= {
103 .recover
= bnxt_fw_reset_recover
,
106 static int bnxt_fw_fatal_recover(struct devlink_health_reporter
*reporter
,
108 struct netlink_ext_ack
*extack
)
110 struct bnxt
*bp
= devlink_health_reporter_priv(reporter
);
111 struct bnxt_fw_reporter_ctx
*fw_reporter_ctx
= priv_ctx
;
117 bp
->fw_health
->fatal
= true;
118 event
= fw_reporter_ctx
->sp_event
;
119 if (event
== BNXT_FW_RESET_NOTIFY_SP_EVENT
)
121 else if (event
== BNXT_FW_EXCEPTION_SP_EVENT
)
122 bnxt_fw_exception(bp
);
128 struct devlink_health_reporter_ops bnxt_dl_fw_fatal_reporter_ops
= {
130 .recover
= bnxt_fw_fatal_recover
,
133 void bnxt_dl_fw_reporters_create(struct bnxt
*bp
)
135 struct bnxt_fw_health
*health
= bp
->fw_health
;
137 if (!bp
->dl
|| !health
)
140 if (!(bp
->fw_cap
& BNXT_FW_CAP_HOT_RESET
) || health
->fw_reset_reporter
)
143 health
->fw_reset_reporter
=
144 devlink_health_reporter_create(bp
->dl
,
145 &bnxt_dl_fw_reset_reporter_ops
,
147 if (IS_ERR(health
->fw_reset_reporter
)) {
148 netdev_warn(bp
->dev
, "Failed to create FW fatal health reporter, rc = %ld\n",
149 PTR_ERR(health
->fw_reset_reporter
));
150 health
->fw_reset_reporter
= NULL
;
151 bp
->fw_cap
&= ~BNXT_FW_CAP_HOT_RESET
;
155 if (!(bp
->fw_cap
& BNXT_FW_CAP_ERROR_RECOVERY
))
158 if (!health
->fw_reporter
) {
159 health
->fw_reporter
=
160 devlink_health_reporter_create(bp
->dl
,
161 &bnxt_dl_fw_reporter_ops
,
163 if (IS_ERR(health
->fw_reporter
)) {
164 netdev_warn(bp
->dev
, "Failed to create FW health reporter, rc = %ld\n",
165 PTR_ERR(health
->fw_reporter
));
166 health
->fw_reporter
= NULL
;
167 bp
->fw_cap
&= ~BNXT_FW_CAP_ERROR_RECOVERY
;
172 if (health
->fw_fatal_reporter
)
175 health
->fw_fatal_reporter
=
176 devlink_health_reporter_create(bp
->dl
,
177 &bnxt_dl_fw_fatal_reporter_ops
,
179 if (IS_ERR(health
->fw_fatal_reporter
)) {
180 netdev_warn(bp
->dev
, "Failed to create FW fatal health reporter, rc = %ld\n",
181 PTR_ERR(health
->fw_fatal_reporter
));
182 health
->fw_fatal_reporter
= NULL
;
183 bp
->fw_cap
&= ~BNXT_FW_CAP_ERROR_RECOVERY
;
187 void bnxt_dl_fw_reporters_destroy(struct bnxt
*bp
, bool all
)
189 struct bnxt_fw_health
*health
= bp
->fw_health
;
191 if (!bp
->dl
|| !health
)
194 if ((all
|| !(bp
->fw_cap
& BNXT_FW_CAP_HOT_RESET
)) &&
195 health
->fw_reset_reporter
) {
196 devlink_health_reporter_destroy(health
->fw_reset_reporter
);
197 health
->fw_reset_reporter
= NULL
;
200 if ((bp
->fw_cap
& BNXT_FW_CAP_ERROR_RECOVERY
) && !all
)
203 if (health
->fw_reporter
) {
204 devlink_health_reporter_destroy(health
->fw_reporter
);
205 health
->fw_reporter
= NULL
;
208 if (health
->fw_fatal_reporter
) {
209 devlink_health_reporter_destroy(health
->fw_fatal_reporter
);
210 health
->fw_fatal_reporter
= NULL
;
214 void bnxt_devlink_health_report(struct bnxt
*bp
, unsigned long event
)
216 struct bnxt_fw_health
*fw_health
= bp
->fw_health
;
217 struct bnxt_fw_reporter_ctx fw_reporter_ctx
;
219 fw_reporter_ctx
.sp_event
= event
;
221 case BNXT_FW_RESET_NOTIFY_SP_EVENT
:
222 if (test_bit(BNXT_STATE_FW_FATAL_COND
, &bp
->state
)) {
223 if (!fw_health
->fw_fatal_reporter
)
226 devlink_health_report(fw_health
->fw_fatal_reporter
,
227 "FW fatal async event received",
231 if (!fw_health
->fw_reset_reporter
)
234 devlink_health_report(fw_health
->fw_reset_reporter
,
235 "FW non-fatal reset event received",
239 case BNXT_FW_EXCEPTION_SP_EVENT
:
240 if (!fw_health
->fw_fatal_reporter
)
243 devlink_health_report(fw_health
->fw_fatal_reporter
,
244 "FW fatal error reported",
250 void bnxt_dl_health_status_update(struct bnxt
*bp
, bool healthy
)
252 struct bnxt_fw_health
*health
= bp
->fw_health
;
256 state
= DEVLINK_HEALTH_REPORTER_STATE_HEALTHY
;
258 state
= DEVLINK_HEALTH_REPORTER_STATE_ERROR
;
261 devlink_health_reporter_state_update(health
->fw_fatal_reporter
,
264 devlink_health_reporter_state_update(health
->fw_reset_reporter
,
267 health
->fatal
= false;
270 void bnxt_dl_health_recovery_done(struct bnxt
*bp
)
272 struct bnxt_fw_health
*hlth
= bp
->fw_health
;
275 devlink_health_reporter_recovery_done(hlth
->fw_fatal_reporter
);
277 devlink_health_reporter_recovery_done(hlth
->fw_reset_reporter
);
280 static int bnxt_dl_info_get(struct devlink
*dl
, struct devlink_info_req
*req
,
281 struct netlink_ext_ack
*extack
);
283 static const struct devlink_ops bnxt_dl_ops
= {
284 #ifdef CONFIG_BNXT_SRIOV
285 .eswitch_mode_set
= bnxt_dl_eswitch_mode_set
,
286 .eswitch_mode_get
= bnxt_dl_eswitch_mode_get
,
287 #endif /* CONFIG_BNXT_SRIOV */
288 .info_get
= bnxt_dl_info_get
,
289 .flash_update
= bnxt_dl_flash_update
,
292 static const struct devlink_ops bnxt_vf_dl_ops
;
294 enum bnxt_dl_param_id
{
295 BNXT_DEVLINK_PARAM_ID_BASE
= DEVLINK_PARAM_GENERIC_ID_MAX
,
296 BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK
,
299 static const struct bnxt_dl_nvm_param nvm_params
[] = {
300 {DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV
, NVM_OFF_ENABLE_SRIOV
,
301 BNXT_NVM_SHARED_CFG
, 1, 1},
302 {DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI
, NVM_OFF_IGNORE_ARI
,
303 BNXT_NVM_SHARED_CFG
, 1, 1},
304 {DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX
,
305 NVM_OFF_MSIX_VEC_PER_PF_MAX
, BNXT_NVM_SHARED_CFG
, 10, 4},
306 {DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN
,
307 NVM_OFF_MSIX_VEC_PER_PF_MIN
, BNXT_NVM_SHARED_CFG
, 7, 4},
308 {BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK
, NVM_OFF_DIS_GRE_VER_CHECK
,
309 BNXT_NVM_SHARED_CFG
, 1, 1},
312 union bnxt_nvm_data
{
317 static void bnxt_copy_to_nvm_data(union bnxt_nvm_data
*dst
,
318 union devlink_param_value
*src
,
319 int nvm_num_bits
, int dl_num_bytes
)
323 if (nvm_num_bits
== 1) {
324 dst
->val8
= src
->vbool
;
327 if (dl_num_bytes
== 4)
329 else if (dl_num_bytes
== 2)
330 val32
= (u32
)src
->vu16
;
331 else if (dl_num_bytes
== 1)
332 val32
= (u32
)src
->vu8
;
333 dst
->val32
= cpu_to_le32(val32
);
336 static void bnxt_copy_from_nvm_data(union devlink_param_value
*dst
,
337 union bnxt_nvm_data
*src
,
338 int nvm_num_bits
, int dl_num_bytes
)
342 if (nvm_num_bits
== 1) {
343 dst
->vbool
= src
->val8
;
346 val32
= le32_to_cpu(src
->val32
);
347 if (dl_num_bytes
== 4)
349 else if (dl_num_bytes
== 2)
350 dst
->vu16
= (u16
)val32
;
351 else if (dl_num_bytes
== 1)
352 dst
->vu8
= (u8
)val32
;
355 static int bnxt_hwrm_get_nvm_cfg_ver(struct bnxt
*bp
,
356 union devlink_param_value
*nvm_cfg_ver
)
358 struct hwrm_nvm_get_variable_input req
= {0};
359 union bnxt_nvm_data
*data
;
360 dma_addr_t data_dma_addr
;
363 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_NVM_GET_VARIABLE
, -1, -1);
364 data
= dma_alloc_coherent(&bp
->pdev
->dev
, sizeof(*data
),
365 &data_dma_addr
, GFP_KERNEL
);
369 req
.dest_data_addr
= cpu_to_le64(data_dma_addr
);
370 req
.data_len
= cpu_to_le16(BNXT_NVM_CFG_VER_BITS
);
371 req
.option_num
= cpu_to_le16(NVM_OFF_NVM_CFG_VER
);
373 rc
= hwrm_send_message_silent(bp
, &req
, sizeof(req
), HWRM_CMD_TIMEOUT
);
375 bnxt_copy_from_nvm_data(nvm_cfg_ver
, data
,
376 BNXT_NVM_CFG_VER_BITS
,
377 BNXT_NVM_CFG_VER_BYTES
);
379 dma_free_coherent(&bp
->pdev
->dev
, sizeof(*data
), data
, data_dma_addr
);
383 static int bnxt_dl_info_put(struct bnxt
*bp
, struct devlink_info_req
*req
,
384 enum bnxt_dl_version_type type
, const char *key
,
390 if ((bp
->flags
& BNXT_FLAG_CHIP_P5
) &&
391 (!strcmp(key
, DEVLINK_INFO_VERSION_GENERIC_FW_NCSI
) ||
392 !strcmp(key
, DEVLINK_INFO_VERSION_GENERIC_FW_ROCE
)))
396 case BNXT_VERSION_FIXED
:
397 return devlink_info_version_fixed_put(req
, key
, buf
);
398 case BNXT_VERSION_RUNNING
:
399 return devlink_info_version_running_put(req
, key
, buf
);
400 case BNXT_VERSION_STORED
:
401 return devlink_info_version_stored_put(req
, key
, buf
);
406 #define HWRM_FW_VER_STR_LEN 16
408 static int bnxt_dl_info_get(struct devlink
*dl
, struct devlink_info_req
*req
,
409 struct netlink_ext_ack
*extack
)
411 struct hwrm_nvm_get_dev_info_output nvm_dev_info
;
412 struct bnxt
*bp
= bnxt_get_bp_from_dl(dl
);
413 union devlink_param_value nvm_cfg_ver
;
414 struct hwrm_ver_get_output
*ver_resp
;
415 char mgmt_ver
[FW_VER_STR_LEN
];
416 char roce_ver
[FW_VER_STR_LEN
];
417 char ncsi_ver
[FW_VER_STR_LEN
];
421 rc
= devlink_info_driver_name_put(req
, DRV_MODULE_NAME
);
425 if (BNXT_PF(bp
) && (bp
->flags
& BNXT_FLAG_DSN_VALID
)) {
426 sprintf(buf
, "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X",
427 bp
->dsn
[7], bp
->dsn
[6], bp
->dsn
[5], bp
->dsn
[4],
428 bp
->dsn
[3], bp
->dsn
[2], bp
->dsn
[1], bp
->dsn
[0]);
429 rc
= devlink_info_serial_number_put(req
, buf
);
434 if (strlen(bp
->board_serialno
)) {
435 rc
= devlink_info_board_serial_number_put(req
, bp
->board_serialno
);
440 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_FIXED
,
441 DEVLINK_INFO_VERSION_GENERIC_BOARD_ID
,
446 sprintf(buf
, "%X", bp
->chip_num
);
447 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_FIXED
,
448 DEVLINK_INFO_VERSION_GENERIC_ASIC_ID
, buf
);
452 ver_resp
= &bp
->ver_resp
;
453 sprintf(buf
, "%X", ver_resp
->chip_rev
);
454 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_FIXED
,
455 DEVLINK_INFO_VERSION_GENERIC_ASIC_REV
, buf
);
459 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_RUNNING
,
460 DEVLINK_INFO_VERSION_GENERIC_FW_PSID
,
466 strncat(buf
, ver_resp
->active_pkg_name
, HWRM_FW_VER_STR_LEN
);
467 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_RUNNING
,
468 DEVLINK_INFO_VERSION_GENERIC_FW
, buf
);
472 if (BNXT_PF(bp
) && !bnxt_hwrm_get_nvm_cfg_ver(bp
, &nvm_cfg_ver
)) {
473 u32 ver
= nvm_cfg_ver
.vu32
;
475 sprintf(buf
, "%X.%X.%X", (ver
>> 16) & 0xF, (ver
>> 8) & 0xF,
477 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_STORED
,
478 DEVLINK_INFO_VERSION_GENERIC_FW_PSID
,
484 if (ver_resp
->flags
& VER_GET_RESP_FLAGS_EXT_VER_AVAIL
) {
485 snprintf(mgmt_ver
, FW_VER_STR_LEN
, "%d.%d.%d.%d",
486 ver_resp
->hwrm_fw_major
, ver_resp
->hwrm_fw_minor
,
487 ver_resp
->hwrm_fw_build
, ver_resp
->hwrm_fw_patch
);
489 snprintf(ncsi_ver
, FW_VER_STR_LEN
, "%d.%d.%d.%d",
490 ver_resp
->mgmt_fw_major
, ver_resp
->mgmt_fw_minor
,
491 ver_resp
->mgmt_fw_build
, ver_resp
->mgmt_fw_patch
);
493 snprintf(roce_ver
, FW_VER_STR_LEN
, "%d.%d.%d.%d",
494 ver_resp
->roce_fw_major
, ver_resp
->roce_fw_minor
,
495 ver_resp
->roce_fw_build
, ver_resp
->roce_fw_patch
);
497 snprintf(mgmt_ver
, FW_VER_STR_LEN
, "%d.%d.%d.%d",
498 ver_resp
->hwrm_fw_maj_8b
, ver_resp
->hwrm_fw_min_8b
,
499 ver_resp
->hwrm_fw_bld_8b
, ver_resp
->hwrm_fw_rsvd_8b
);
501 snprintf(ncsi_ver
, FW_VER_STR_LEN
, "%d.%d.%d.%d",
502 ver_resp
->mgmt_fw_maj_8b
, ver_resp
->mgmt_fw_min_8b
,
503 ver_resp
->mgmt_fw_bld_8b
, ver_resp
->mgmt_fw_rsvd_8b
);
505 snprintf(roce_ver
, FW_VER_STR_LEN
, "%d.%d.%d.%d",
506 ver_resp
->roce_fw_maj_8b
, ver_resp
->roce_fw_min_8b
,
507 ver_resp
->roce_fw_bld_8b
, ver_resp
->roce_fw_rsvd_8b
);
509 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_RUNNING
,
510 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT
, mgmt_ver
);
514 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_RUNNING
,
515 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API
,
520 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_RUNNING
,
521 DEVLINK_INFO_VERSION_GENERIC_FW_NCSI
, ncsi_ver
);
525 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_RUNNING
,
526 DEVLINK_INFO_VERSION_GENERIC_FW_ROCE
, roce_ver
);
530 rc
= bnxt_hwrm_nvm_get_dev_info(bp
, &nvm_dev_info
);
532 !(nvm_dev_info
.flags
& NVM_GET_DEV_INFO_RESP_FLAGS_FW_VER_VALID
))
536 strncat(buf
, nvm_dev_info
.pkg_name
, HWRM_FW_VER_STR_LEN
);
537 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_STORED
,
538 DEVLINK_INFO_VERSION_GENERIC_FW
, buf
);
542 snprintf(mgmt_ver
, FW_VER_STR_LEN
, "%d.%d.%d.%d",
543 nvm_dev_info
.hwrm_fw_major
, nvm_dev_info
.hwrm_fw_minor
,
544 nvm_dev_info
.hwrm_fw_build
, nvm_dev_info
.hwrm_fw_patch
);
545 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_STORED
,
546 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT
, mgmt_ver
);
550 snprintf(ncsi_ver
, FW_VER_STR_LEN
, "%d.%d.%d.%d",
551 nvm_dev_info
.mgmt_fw_major
, nvm_dev_info
.mgmt_fw_minor
,
552 nvm_dev_info
.mgmt_fw_build
, nvm_dev_info
.mgmt_fw_patch
);
553 rc
= bnxt_dl_info_put(bp
, req
, BNXT_VERSION_STORED
,
554 DEVLINK_INFO_VERSION_GENERIC_FW_NCSI
, ncsi_ver
);
558 snprintf(roce_ver
, FW_VER_STR_LEN
, "%d.%d.%d.%d",
559 nvm_dev_info
.roce_fw_major
, nvm_dev_info
.roce_fw_minor
,
560 nvm_dev_info
.roce_fw_build
, nvm_dev_info
.roce_fw_patch
);
561 return bnxt_dl_info_put(bp
, req
, BNXT_VERSION_STORED
,
562 DEVLINK_INFO_VERSION_GENERIC_FW_ROCE
, roce_ver
);
565 static int bnxt_hwrm_nvm_req(struct bnxt
*bp
, u32 param_id
, void *msg
,
566 int msg_len
, union devlink_param_value
*val
)
568 struct hwrm_nvm_get_variable_input
*req
= msg
;
569 struct bnxt_dl_nvm_param nvm_param
;
570 union bnxt_nvm_data
*data
;
571 dma_addr_t data_dma_addr
;
574 /* Get/Set NVM CFG parameter is supported only on PFs */
578 for (i
= 0; i
< ARRAY_SIZE(nvm_params
); i
++) {
579 if (nvm_params
[i
].id
== param_id
) {
580 nvm_param
= nvm_params
[i
];
585 if (i
== ARRAY_SIZE(nvm_params
))
588 if (nvm_param
.dir_type
== BNXT_NVM_PORT_CFG
)
589 idx
= bp
->pf
.port_id
;
590 else if (nvm_param
.dir_type
== BNXT_NVM_FUNC_CFG
)
591 idx
= bp
->pf
.fw_fid
- BNXT_FIRST_PF_FID
;
593 data
= dma_alloc_coherent(&bp
->pdev
->dev
, sizeof(*data
),
594 &data_dma_addr
, GFP_KERNEL
);
598 req
->dest_data_addr
= cpu_to_le64(data_dma_addr
);
599 req
->data_len
= cpu_to_le16(nvm_param
.nvm_num_bits
);
600 req
->option_num
= cpu_to_le16(nvm_param
.offset
);
601 req
->index_0
= cpu_to_le16(idx
);
603 req
->dimensions
= cpu_to_le16(1);
605 if (req
->req_type
== cpu_to_le16(HWRM_NVM_SET_VARIABLE
)) {
606 bnxt_copy_to_nvm_data(data
, val
, nvm_param
.nvm_num_bits
,
607 nvm_param
.dl_num_bytes
);
608 rc
= hwrm_send_message(bp
, msg
, msg_len
, HWRM_CMD_TIMEOUT
);
610 rc
= hwrm_send_message_silent(bp
, msg
, msg_len
,
613 bnxt_copy_from_nvm_data(val
, data
,
614 nvm_param
.nvm_num_bits
,
615 nvm_param
.dl_num_bytes
);
617 struct hwrm_err_output
*resp
= bp
->hwrm_cmd_resp_addr
;
620 NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST
)
624 dma_free_coherent(&bp
->pdev
->dev
, sizeof(*data
), data
, data_dma_addr
);
626 netdev_err(bp
->dev
, "PF does not have admin privileges to modify NVM config\n");
630 static int bnxt_dl_nvm_param_get(struct devlink
*dl
, u32 id
,
631 struct devlink_param_gset_ctx
*ctx
)
633 struct hwrm_nvm_get_variable_input req
= {0};
634 struct bnxt
*bp
= bnxt_get_bp_from_dl(dl
);
637 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_NVM_GET_VARIABLE
, -1, -1);
638 rc
= bnxt_hwrm_nvm_req(bp
, id
, &req
, sizeof(req
), &ctx
->val
);
640 if (id
== BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK
)
641 ctx
->val
.vbool
= !ctx
->val
.vbool
;
646 static int bnxt_dl_nvm_param_set(struct devlink
*dl
, u32 id
,
647 struct devlink_param_gset_ctx
*ctx
)
649 struct hwrm_nvm_set_variable_input req
= {0};
650 struct bnxt
*bp
= bnxt_get_bp_from_dl(dl
);
652 bnxt_hwrm_cmd_hdr_init(bp
, &req
, HWRM_NVM_SET_VARIABLE
, -1, -1);
654 if (id
== BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK
)
655 ctx
->val
.vbool
= !ctx
->val
.vbool
;
657 return bnxt_hwrm_nvm_req(bp
, id
, &req
, sizeof(req
), &ctx
->val
);
660 static int bnxt_dl_msix_validate(struct devlink
*dl
, u32 id
,
661 union devlink_param_value val
,
662 struct netlink_ext_ack
*extack
)
666 if (id
== DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX
)
667 max_val
= BNXT_MSIX_VEC_MAX
;
669 if (id
== DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN
)
670 max_val
= BNXT_MSIX_VEC_MIN_MAX
;
672 if (val
.vu32
> max_val
) {
673 NL_SET_ERR_MSG_MOD(extack
, "MSIX value is exceeding the range");
680 static const struct devlink_param bnxt_dl_params
[] = {
681 DEVLINK_PARAM_GENERIC(ENABLE_SRIOV
,
682 BIT(DEVLINK_PARAM_CMODE_PERMANENT
),
683 bnxt_dl_nvm_param_get
, bnxt_dl_nvm_param_set
,
685 DEVLINK_PARAM_GENERIC(IGNORE_ARI
,
686 BIT(DEVLINK_PARAM_CMODE_PERMANENT
),
687 bnxt_dl_nvm_param_get
, bnxt_dl_nvm_param_set
,
689 DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MAX
,
690 BIT(DEVLINK_PARAM_CMODE_PERMANENT
),
691 bnxt_dl_nvm_param_get
, bnxt_dl_nvm_param_set
,
692 bnxt_dl_msix_validate
),
693 DEVLINK_PARAM_GENERIC(MSIX_VEC_PER_PF_MIN
,
694 BIT(DEVLINK_PARAM_CMODE_PERMANENT
),
695 bnxt_dl_nvm_param_get
, bnxt_dl_nvm_param_set
,
696 bnxt_dl_msix_validate
),
697 DEVLINK_PARAM_DRIVER(BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK
,
698 "gre_ver_check", DEVLINK_PARAM_TYPE_BOOL
,
699 BIT(DEVLINK_PARAM_CMODE_PERMANENT
),
700 bnxt_dl_nvm_param_get
, bnxt_dl_nvm_param_set
,
704 static const struct devlink_param bnxt_dl_port_params
[] = {
707 static int bnxt_dl_params_register(struct bnxt
*bp
)
711 if (bp
->hwrm_spec_code
< 0x10600)
714 rc
= devlink_params_register(bp
->dl
, bnxt_dl_params
,
715 ARRAY_SIZE(bnxt_dl_params
));
717 netdev_warn(bp
->dev
, "devlink_params_register failed. rc=%d\n",
721 rc
= devlink_port_params_register(&bp
->dl_port
, bnxt_dl_port_params
,
722 ARRAY_SIZE(bnxt_dl_port_params
));
724 netdev_err(bp
->dev
, "devlink_port_params_register failed\n");
725 devlink_params_unregister(bp
->dl
, bnxt_dl_params
,
726 ARRAY_SIZE(bnxt_dl_params
));
729 devlink_params_publish(bp
->dl
);
734 static void bnxt_dl_params_unregister(struct bnxt
*bp
)
736 if (bp
->hwrm_spec_code
< 0x10600)
739 devlink_params_unregister(bp
->dl
, bnxt_dl_params
,
740 ARRAY_SIZE(bnxt_dl_params
));
741 devlink_port_params_unregister(&bp
->dl_port
, bnxt_dl_port_params
,
742 ARRAY_SIZE(bnxt_dl_port_params
));
745 int bnxt_dl_register(struct bnxt
*bp
)
747 struct devlink_port_attrs attrs
= {};
752 dl
= devlink_alloc(&bnxt_dl_ops
, sizeof(struct bnxt_dl
));
754 dl
= devlink_alloc(&bnxt_vf_dl_ops
, sizeof(struct bnxt_dl
));
756 netdev_warn(bp
->dev
, "devlink_alloc failed\n");
760 bnxt_link_bp_to_dl(bp
, dl
);
762 /* Add switchdev eswitch mode setting, if SRIOV supported */
763 if (pci_find_ext_capability(bp
->pdev
, PCI_EXT_CAP_ID_SRIOV
) &&
764 bp
->hwrm_spec_code
> 0x10803)
765 bp
->eswitch_mode
= DEVLINK_ESWITCH_MODE_LEGACY
;
767 rc
= devlink_register(dl
, &bp
->pdev
->dev
);
769 netdev_warn(bp
->dev
, "devlink_register failed. rc=%d\n", rc
);
776 attrs
.flavour
= DEVLINK_PORT_FLAVOUR_PHYSICAL
;
777 attrs
.phys
.port_number
= bp
->pf
.port_id
;
778 memcpy(attrs
.switch_id
.id
, bp
->dsn
, sizeof(bp
->dsn
));
779 attrs
.switch_id
.id_len
= sizeof(bp
->dsn
);
780 devlink_port_attrs_set(&bp
->dl_port
, &attrs
);
781 rc
= devlink_port_register(dl
, &bp
->dl_port
, bp
->pf
.port_id
);
783 netdev_err(bp
->dev
, "devlink_port_register failed\n");
787 rc
= bnxt_dl_params_register(bp
);
789 goto err_dl_port_unreg
;
794 devlink_port_unregister(&bp
->dl_port
);
796 devlink_unregister(dl
);
798 bnxt_link_bp_to_dl(bp
, NULL
);
803 void bnxt_dl_unregister(struct bnxt
*bp
)
805 struct devlink
*dl
= bp
->dl
;
811 bnxt_dl_params_unregister(bp
);
812 devlink_port_unregister(&bp
->dl_port
);
814 devlink_unregister(dl
);