1df69ba43SShannon Nelson // SPDX-License-Identifier: GPL-2.0 2df69ba43SShannon Nelson /* Copyright(c) 2017 - 2019 Pensando Systems, Inc */ 3df69ba43SShannon Nelson 4df69ba43SShannon Nelson #include <linux/module.h> 5df69ba43SShannon Nelson #include <linux/netdevice.h> 6df69ba43SShannon Nelson 7df69ba43SShannon Nelson #include "ionic.h" 8df69ba43SShannon Nelson #include "ionic_bus.h" 9beead698SShannon Nelson #include "ionic_lif.h" 10df69ba43SShannon Nelson #include "ionic_devlink.h" 11df69ba43SShannon Nelson 1230b5191aSShannon Nelson static int ionic_dl_flash_update(struct devlink *dl, 13bc75c054SJacob Keller struct devlink_flash_update_params *params, 1430b5191aSShannon Nelson struct netlink_ext_ack *extack) 1530b5191aSShannon Nelson { 1630b5191aSShannon Nelson struct ionic *ionic = devlink_priv(dl); 1730b5191aSShannon Nelson 18b44cfd4fSJacob Keller return ionic_firmware_update(ionic->lif, params->fw, extack); 1930b5191aSShannon Nelson } 2030b5191aSShannon Nelson 21df69ba43SShannon Nelson static int ionic_dl_info_get(struct devlink *dl, struct devlink_info_req *req, 22df69ba43SShannon Nelson struct netlink_ext_ack *extack) 23df69ba43SShannon Nelson { 24fbfb8031SShannon Nelson struct ionic *ionic = devlink_priv(dl); 25fbfb8031SShannon Nelson struct ionic_dev *idev = &ionic->idev; 26fbfb8031SShannon Nelson char buf[16]; 27fbfb8031SShannon Nelson int err = 0; 28fbfb8031SShannon Nelson 29fbfb8031SShannon Nelson err = devlink_info_version_running_put(req, 30fbfb8031SShannon Nelson DEVLINK_INFO_VERSION_GENERIC_FW, 31fbfb8031SShannon Nelson idev->dev_info.fw_version); 32fbfb8031SShannon Nelson if (err) 33da0729e8SShannon Nelson return err; 34fbfb8031SShannon Nelson 35fbfb8031SShannon Nelson snprintf(buf, sizeof(buf), "0x%x", idev->dev_info.asic_type); 36fbfb8031SShannon Nelson err = devlink_info_version_fixed_put(req, 37fbfb8031SShannon Nelson DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, 38fbfb8031SShannon Nelson buf); 39fbfb8031SShannon Nelson if (err) 40da0729e8SShannon Nelson return err; 41fbfb8031SShannon Nelson 42fbfb8031SShannon Nelson snprintf(buf, sizeof(buf), "0x%x", idev->dev_info.asic_rev); 43fbfb8031SShannon Nelson err = devlink_info_version_fixed_put(req, 44fbfb8031SShannon Nelson DEVLINK_INFO_VERSION_GENERIC_ASIC_REV, 45fbfb8031SShannon Nelson buf); 46fbfb8031SShannon Nelson if (err) 47da0729e8SShannon Nelson return err; 48fbfb8031SShannon Nelson 49fbfb8031SShannon Nelson err = devlink_info_serial_number_put(req, idev->dev_info.serial_num); 50fbfb8031SShannon Nelson 51fbfb8031SShannon Nelson return err; 52df69ba43SShannon Nelson } 53df69ba43SShannon Nelson 54df69ba43SShannon Nelson static const struct devlink_ops ionic_dl_ops = { 55df69ba43SShannon Nelson .info_get = ionic_dl_info_get, 5630b5191aSShannon Nelson .flash_update = ionic_dl_flash_update, 57df69ba43SShannon Nelson }; 58df69ba43SShannon Nelson 59df69ba43SShannon Nelson struct ionic *ionic_devlink_alloc(struct device *dev) 60df69ba43SShannon Nelson { 61df69ba43SShannon Nelson struct devlink *dl; 62df69ba43SShannon Nelson 63919d13a7SLeon Romanovsky dl = devlink_alloc(&ionic_dl_ops, sizeof(struct ionic), dev); 64*4a54903fSShannon Nelson if (!dl) 65*4a54903fSShannon Nelson return NULL; 66df69ba43SShannon Nelson 67df69ba43SShannon Nelson return devlink_priv(dl); 68df69ba43SShannon Nelson } 69df69ba43SShannon Nelson 70df69ba43SShannon Nelson void ionic_devlink_free(struct ionic *ionic) 71df69ba43SShannon Nelson { 72df69ba43SShannon Nelson struct devlink *dl = priv_to_devlink(ionic); 73df69ba43SShannon Nelson 74df69ba43SShannon Nelson devlink_free(dl); 75df69ba43SShannon Nelson } 76fbfb8031SShannon Nelson 77fbfb8031SShannon Nelson int ionic_devlink_register(struct ionic *ionic) 78fbfb8031SShannon Nelson { 79fbfb8031SShannon Nelson struct devlink *dl = priv_to_devlink(ionic); 8071ad8d55SDanielle Ratson struct devlink_port_attrs attrs = {}; 81fbfb8031SShannon Nelson int err; 82fbfb8031SShannon Nelson 8371ad8d55SDanielle Ratson attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 8471ad8d55SDanielle Ratson devlink_port_attrs_set(&ionic->dl_port, &attrs); 85beead698SShannon Nelson err = devlink_port_register(dl, &ionic->dl_port, 0); 86c2255ff4SLeon Romanovsky if (err) { 87beead698SShannon Nelson dev_err(ionic->dev, "devlink_port_register failed: %d\n", err); 88fbfb8031SShannon Nelson return err; 89fbfb8031SShannon Nelson } 90fbfb8031SShannon Nelson 91ac73d4bfSJiri Pirko SET_NETDEV_DEVLINK_PORT(ionic->lif->netdev, &ionic->dl_port); 927911c8bdSLeon Romanovsky devlink_register(dl); 93c2255ff4SLeon Romanovsky return 0; 94c2255ff4SLeon Romanovsky } 95c2255ff4SLeon Romanovsky 96fbfb8031SShannon Nelson void ionic_devlink_unregister(struct ionic *ionic) 97fbfb8031SShannon Nelson { 98fbfb8031SShannon Nelson struct devlink *dl = priv_to_devlink(ionic); 99fbfb8031SShannon Nelson 100fbfb8031SShannon Nelson devlink_unregister(dl); 1017911c8bdSLeon Romanovsky devlink_port_unregister(&ionic->dl_port); 102fbfb8031SShannon Nelson } 103