1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ 3 4 #include <linux/module.h> 5 #include <linux/netdevice.h> 6 7 #include "ionic.h" 8 #include "ionic_bus.h" 9 #include "ionic_lif.h" 10 #include "ionic_devlink.h" 11 12 static int ionic_dl_flash_update(struct devlink *dl, 13 const char *fwname, 14 const char *component, 15 struct netlink_ext_ack *extack) 16 { 17 struct ionic *ionic = devlink_priv(dl); 18 19 if (component) 20 return -EOPNOTSUPP; 21 22 return ionic_firmware_update(ionic->lif, fwname, extack); 23 } 24 25 static int ionic_dl_info_get(struct devlink *dl, struct devlink_info_req *req, 26 struct netlink_ext_ack *extack) 27 { 28 struct ionic *ionic = devlink_priv(dl); 29 struct ionic_dev *idev = &ionic->idev; 30 char buf[16]; 31 int err = 0; 32 33 err = devlink_info_driver_name_put(req, IONIC_DRV_NAME); 34 if (err) 35 return err; 36 37 err = devlink_info_version_running_put(req, 38 DEVLINK_INFO_VERSION_GENERIC_FW, 39 idev->dev_info.fw_version); 40 if (err) 41 return err; 42 43 snprintf(buf, sizeof(buf), "0x%x", idev->dev_info.asic_type); 44 err = devlink_info_version_fixed_put(req, 45 DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, 46 buf); 47 if (err) 48 return err; 49 50 snprintf(buf, sizeof(buf), "0x%x", idev->dev_info.asic_rev); 51 err = devlink_info_version_fixed_put(req, 52 DEVLINK_INFO_VERSION_GENERIC_ASIC_REV, 53 buf); 54 if (err) 55 return err; 56 57 err = devlink_info_serial_number_put(req, idev->dev_info.serial_num); 58 59 return err; 60 } 61 62 static const struct devlink_ops ionic_dl_ops = { 63 .info_get = ionic_dl_info_get, 64 .flash_update = ionic_dl_flash_update, 65 }; 66 67 struct ionic *ionic_devlink_alloc(struct device *dev) 68 { 69 struct devlink *dl; 70 71 dl = devlink_alloc(&ionic_dl_ops, sizeof(struct ionic)); 72 73 return devlink_priv(dl); 74 } 75 76 void ionic_devlink_free(struct ionic *ionic) 77 { 78 struct devlink *dl = priv_to_devlink(ionic); 79 80 devlink_free(dl); 81 } 82 83 int ionic_devlink_register(struct ionic *ionic) 84 { 85 struct devlink *dl = priv_to_devlink(ionic); 86 struct devlink_port_attrs attrs = {}; 87 int err; 88 89 err = devlink_register(dl, ionic->dev); 90 if (err) { 91 dev_warn(ionic->dev, "devlink_register failed: %d\n", err); 92 return err; 93 } 94 95 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 96 devlink_port_attrs_set(&ionic->dl_port, &attrs); 97 err = devlink_port_register(dl, &ionic->dl_port, 0); 98 if (err) 99 dev_err(ionic->dev, "devlink_port_register failed: %d\n", err); 100 else 101 devlink_port_type_eth_set(&ionic->dl_port, 102 ionic->lif->netdev); 103 104 return err; 105 } 106 107 void ionic_devlink_unregister(struct ionic *ionic) 108 { 109 struct devlink *dl = priv_to_devlink(ionic); 110 111 if (ionic->dl_port.registered) 112 devlink_port_unregister(&ionic->dl_port); 113 devlink_unregister(dl); 114 } 115