1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */ 3 4 #include <net/devlink.h> 5 6 #include "prestera_devlink.h" 7 8 static int prestera_dl_info_get(struct devlink *dl, 9 struct devlink_info_req *req, 10 struct netlink_ext_ack *extack) 11 { 12 struct prestera_switch *sw = devlink_priv(dl); 13 char buf[16]; 14 int err; 15 16 err = devlink_info_driver_name_put(req, PRESTERA_DRV_NAME); 17 if (err) 18 return err; 19 20 snprintf(buf, sizeof(buf), "%d.%d.%d", 21 sw->dev->fw_rev.maj, 22 sw->dev->fw_rev.min, 23 sw->dev->fw_rev.sub); 24 25 return devlink_info_version_running_put(req, 26 DEVLINK_INFO_VERSION_GENERIC_FW, 27 buf); 28 } 29 30 static const struct devlink_ops prestera_dl_ops = { 31 .info_get = prestera_dl_info_get, 32 }; 33 34 struct prestera_switch *prestera_devlink_alloc(void) 35 { 36 struct devlink *dl; 37 38 dl = devlink_alloc(&prestera_dl_ops, sizeof(struct prestera_switch)); 39 40 return devlink_priv(dl); 41 } 42 43 void prestera_devlink_free(struct prestera_switch *sw) 44 { 45 struct devlink *dl = priv_to_devlink(sw); 46 47 devlink_free(dl); 48 } 49 50 int prestera_devlink_register(struct prestera_switch *sw) 51 { 52 struct devlink *dl = priv_to_devlink(sw); 53 int err; 54 55 err = devlink_register(dl, sw->dev->dev); 56 if (err) 57 dev_err(prestera_dev(sw), "devlink_register failed: %d\n", err); 58 59 return err; 60 } 61 62 void prestera_devlink_unregister(struct prestera_switch *sw) 63 { 64 struct devlink *dl = priv_to_devlink(sw); 65 66 devlink_unregister(dl); 67 } 68 69 int prestera_devlink_port_register(struct prestera_port *port) 70 { 71 struct prestera_switch *sw = port->sw; 72 struct devlink *dl = priv_to_devlink(sw); 73 struct devlink_port_attrs attrs = {}; 74 int err; 75 76 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 77 attrs.phys.port_number = port->fp_id; 78 attrs.switch_id.id_len = sizeof(sw->id); 79 memcpy(attrs.switch_id.id, &sw->id, attrs.switch_id.id_len); 80 81 devlink_port_attrs_set(&port->dl_port, &attrs); 82 83 err = devlink_port_register(dl, &port->dl_port, port->fp_id); 84 if (err) { 85 dev_err(prestera_dev(sw), "devlink_port_register failed: %d\n", err); 86 return err; 87 } 88 89 return 0; 90 } 91 92 void prestera_devlink_port_unregister(struct prestera_port *port) 93 { 94 devlink_port_unregister(&port->dl_port); 95 } 96 97 void prestera_devlink_port_set(struct prestera_port *port) 98 { 99 devlink_port_type_eth_set(&port->dl_port, port->dev); 100 } 101 102 void prestera_devlink_port_clear(struct prestera_port *port) 103 { 104 devlink_port_type_clear(&port->dl_port); 105 } 106 107 struct devlink_port *prestera_devlink_get_port(struct net_device *dev) 108 { 109 struct prestera_port *port = netdev_priv(dev); 110 111 return &port->dl_port; 112 } 113