1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 /* Copyright (c) Amazon.com, Inc. or its affiliates. 3 * All rights reserved. 4 */ 5 6 #include "linux/pci.h" 7 #include "ena_devlink.h" 8 #include "ena_phc.h" 9 10 static int ena_devlink_enable_phc_validate(struct devlink *devlink, u32 id, 11 union devlink_param_value val, 12 struct netlink_ext_ack *extack) 13 { 14 struct ena_adapter *adapter = ENA_DEVLINK_PRIV(devlink); 15 16 if (!val.vbool) 17 return 0; 18 19 if (!ena_com_phc_supported(adapter->ena_dev)) { 20 NL_SET_ERR_MSG_MOD(extack, "Device doesn't support PHC"); 21 return -EOPNOTSUPP; 22 } 23 24 return 0; 25 } 26 27 static const struct devlink_param ena_devlink_params[] = { 28 DEVLINK_PARAM_GENERIC(ENABLE_PHC, 29 BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), 30 NULL, 31 NULL, 32 ena_devlink_enable_phc_validate), 33 }; 34 35 void ena_devlink_params_get(struct devlink *devlink) 36 { 37 struct ena_adapter *adapter = ENA_DEVLINK_PRIV(devlink); 38 union devlink_param_value val; 39 int err; 40 41 err = devl_param_driverinit_value_get(devlink, 42 DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC, 43 &val); 44 if (err) { 45 netdev_err(adapter->netdev, "Failed to query PHC param\n"); 46 return; 47 } 48 49 ena_phc_enable(adapter, val.vbool); 50 } 51 52 void ena_devlink_disable_phc_param(struct devlink *devlink) 53 { 54 union devlink_param_value value; 55 56 value.vbool = false; 57 devl_param_driverinit_value_set(devlink, 58 DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC, 59 value); 60 } 61 62 static void ena_devlink_port_register(struct devlink *devlink) 63 { 64 struct ena_adapter *adapter = ENA_DEVLINK_PRIV(devlink); 65 struct devlink_port_attrs attrs = {}; 66 67 attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 68 devlink_port_attrs_set(&adapter->devlink_port, &attrs); 69 devl_port_register(devlink, &adapter->devlink_port, 0); 70 } 71 72 static void ena_devlink_port_unregister(struct devlink *devlink) 73 { 74 struct ena_adapter *adapter = ENA_DEVLINK_PRIV(devlink); 75 76 devl_port_unregister(&adapter->devlink_port); 77 } 78 79 static int ena_devlink_reload_down(struct devlink *devlink, 80 bool netns_change, 81 enum devlink_reload_action action, 82 enum devlink_reload_limit limit, 83 struct netlink_ext_ack *extack) 84 { 85 struct ena_adapter *adapter = ENA_DEVLINK_PRIV(devlink); 86 87 if (netns_change) { 88 NL_SET_ERR_MSG_MOD(extack, 89 "Namespace change is not supported"); 90 return -EOPNOTSUPP; 91 } 92 93 ena_devlink_port_unregister(devlink); 94 95 rtnl_lock(); 96 ena_destroy_device(adapter, false); 97 rtnl_unlock(); 98 99 return 0; 100 } 101 102 static int ena_devlink_reload_up(struct devlink *devlink, 103 enum devlink_reload_action action, 104 enum devlink_reload_limit limit, 105 u32 *actions_performed, 106 struct netlink_ext_ack *extack) 107 { 108 struct ena_adapter *adapter = ENA_DEVLINK_PRIV(devlink); 109 int err = 0; 110 111 rtnl_lock(); 112 /* Check that no other routine initialized the device (e.g. 113 * ena_fw_reset_device()). Also we're under devlink_mutex here, 114 * so devlink isn't freed under our feet. 115 */ 116 if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) 117 err = ena_restore_device(adapter); 118 119 rtnl_unlock(); 120 121 ena_devlink_port_register(devlink); 122 123 if (!err) 124 *actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT); 125 126 return err; 127 } 128 129 static const struct devlink_ops ena_devlink_ops = { 130 .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT), 131 .reload_down = ena_devlink_reload_down, 132 .reload_up = ena_devlink_reload_up, 133 }; 134 135 static int ena_devlink_configure_params(struct devlink *devlink) 136 { 137 struct ena_adapter *adapter = ENA_DEVLINK_PRIV(devlink); 138 union devlink_param_value value; 139 int rc; 140 141 rc = devlink_params_register(devlink, ena_devlink_params, 142 ARRAY_SIZE(ena_devlink_params)); 143 if (rc) { 144 netdev_err(adapter->netdev, "Failed to register devlink params\n"); 145 return rc; 146 } 147 148 value.vbool = ena_phc_is_enabled(adapter); 149 devl_param_driverinit_value_set(devlink, 150 DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC, 151 value); 152 153 return 0; 154 } 155 156 struct devlink *ena_devlink_alloc(struct ena_adapter *adapter) 157 { 158 struct device *dev = &adapter->pdev->dev; 159 struct devlink *devlink; 160 161 devlink = devlink_alloc(&ena_devlink_ops, 162 sizeof(struct ena_adapter *), 163 dev); 164 if (!devlink) { 165 netdev_err(adapter->netdev, 166 "Failed to allocate devlink struct\n"); 167 return NULL; 168 } 169 170 ENA_DEVLINK_PRIV(devlink) = adapter; 171 adapter->devlink = devlink; 172 173 if (ena_devlink_configure_params(devlink)) 174 goto free_devlink; 175 176 return devlink; 177 178 free_devlink: 179 devlink_free(devlink); 180 return NULL; 181 } 182 183 static void ena_devlink_configure_params_clean(struct devlink *devlink) 184 { 185 devlink_params_unregister(devlink, ena_devlink_params, 186 ARRAY_SIZE(ena_devlink_params)); 187 } 188 189 void ena_devlink_free(struct devlink *devlink) 190 { 191 ena_devlink_configure_params_clean(devlink); 192 193 devlink_free(devlink); 194 } 195 196 void ena_devlink_register(struct devlink *devlink, struct device *dev) 197 { 198 devl_lock(devlink); 199 ena_devlink_port_register(devlink); 200 devl_register(devlink); 201 devl_unlock(devlink); 202 } 203 204 void ena_devlink_unregister(struct devlink *devlink) 205 { 206 devl_lock(devlink); 207 ena_devlink_port_unregister(devlink); 208 devl_unregister(devlink); 209 devl_unlock(devlink); 210 } 211