18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/module.h> 58c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include "ionic.h" 88c2ecf20Sopenharmony_ci#include "ionic_bus.h" 98c2ecf20Sopenharmony_ci#include "ionic_lif.h" 108c2ecf20Sopenharmony_ci#include "ionic_devlink.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistatic int ionic_dl_flash_update(struct devlink *dl, 138c2ecf20Sopenharmony_ci struct devlink_flash_update_params *params, 148c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci struct ionic *ionic = devlink_priv(dl); 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci return ionic_firmware_update(ionic->lif, params->file_name, extack); 198c2ecf20Sopenharmony_ci} 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic int ionic_dl_info_get(struct devlink *dl, struct devlink_info_req *req, 228c2ecf20Sopenharmony_ci struct netlink_ext_ack *extack) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci struct ionic *ionic = devlink_priv(dl); 258c2ecf20Sopenharmony_ci struct ionic_dev *idev = &ionic->idev; 268c2ecf20Sopenharmony_ci char buf[16]; 278c2ecf20Sopenharmony_ci int err = 0; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci err = devlink_info_driver_name_put(req, IONIC_DRV_NAME); 308c2ecf20Sopenharmony_ci if (err) 318c2ecf20Sopenharmony_ci return err; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci err = devlink_info_version_running_put(req, 348c2ecf20Sopenharmony_ci DEVLINK_INFO_VERSION_GENERIC_FW, 358c2ecf20Sopenharmony_ci idev->dev_info.fw_version); 368c2ecf20Sopenharmony_ci if (err) 378c2ecf20Sopenharmony_ci return err; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci snprintf(buf, sizeof(buf), "0x%x", idev->dev_info.asic_type); 408c2ecf20Sopenharmony_ci err = devlink_info_version_fixed_put(req, 418c2ecf20Sopenharmony_ci DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, 428c2ecf20Sopenharmony_ci buf); 438c2ecf20Sopenharmony_ci if (err) 448c2ecf20Sopenharmony_ci return err; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci snprintf(buf, sizeof(buf), "0x%x", idev->dev_info.asic_rev); 478c2ecf20Sopenharmony_ci err = devlink_info_version_fixed_put(req, 488c2ecf20Sopenharmony_ci DEVLINK_INFO_VERSION_GENERIC_ASIC_REV, 498c2ecf20Sopenharmony_ci buf); 508c2ecf20Sopenharmony_ci if (err) 518c2ecf20Sopenharmony_ci return err; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci err = devlink_info_serial_number_put(req, idev->dev_info.serial_num); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci return err; 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic const struct devlink_ops ionic_dl_ops = { 598c2ecf20Sopenharmony_ci .info_get = ionic_dl_info_get, 608c2ecf20Sopenharmony_ci .flash_update = ionic_dl_flash_update, 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistruct ionic *ionic_devlink_alloc(struct device *dev) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci struct devlink *dl; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci dl = devlink_alloc(&ionic_dl_ops, sizeof(struct ionic)); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci return devlink_priv(dl); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_civoid ionic_devlink_free(struct ionic *ionic) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci struct devlink *dl = priv_to_devlink(ionic); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci devlink_free(dl); 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ciint ionic_devlink_register(struct ionic *ionic) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci struct devlink *dl = priv_to_devlink(ionic); 828c2ecf20Sopenharmony_ci struct devlink_port_attrs attrs = {}; 838c2ecf20Sopenharmony_ci int err; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci err = devlink_register(dl, ionic->dev); 868c2ecf20Sopenharmony_ci if (err) { 878c2ecf20Sopenharmony_ci dev_warn(ionic->dev, "devlink_register failed: %d\n", err); 888c2ecf20Sopenharmony_ci return err; 898c2ecf20Sopenharmony_ci } 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 928c2ecf20Sopenharmony_ci devlink_port_attrs_set(&ionic->dl_port, &attrs); 938c2ecf20Sopenharmony_ci err = devlink_port_register(dl, &ionic->dl_port, 0); 948c2ecf20Sopenharmony_ci if (err) { 958c2ecf20Sopenharmony_ci dev_err(ionic->dev, "devlink_port_register failed: %d\n", err); 968c2ecf20Sopenharmony_ci devlink_unregister(dl); 978c2ecf20Sopenharmony_ci return err; 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci devlink_port_type_eth_set(&ionic->dl_port, ionic->lif->netdev); 1018c2ecf20Sopenharmony_ci return 0; 1028c2ecf20Sopenharmony_ci} 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_civoid ionic_devlink_unregister(struct ionic *ionic) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci struct devlink *dl = priv_to_devlink(ionic); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci devlink_port_unregister(&ionic->dl_port); 1098c2ecf20Sopenharmony_ci devlink_unregister(dl); 1108c2ecf20Sopenharmony_ci} 111