1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * System Control and Management Interface (SCMI) Base Protocol 4 * 5 * Copyright (C) 2018-2021 ARM Ltd. 6 */ 7 8 #define pr_fmt(fmt) "SCMI Notifications BASE - " fmt 9 10 #include <linux/module.h> 11 #include <linux/scmi_protocol.h> 12 13 #include "common.h" 14 #include "notify.h" 15 16 /* Updated only after ALL the mandatory features for that version are merged */ 17 #define SCMI_PROTOCOL_SUPPORTED_VERSION 0x20000 18 19 #define SCMI_BASE_NUM_SOURCES 1 20 #define SCMI_BASE_MAX_CMD_ERR_COUNT 1024 21 22 enum scmi_base_protocol_cmd { 23 BASE_DISCOVER_VENDOR = 0x3, 24 BASE_DISCOVER_SUB_VENDOR = 0x4, 25 BASE_DISCOVER_IMPLEMENT_VERSION = 0x5, 26 BASE_DISCOVER_LIST_PROTOCOLS = 0x6, 27 BASE_DISCOVER_AGENT = 0x7, 28 BASE_NOTIFY_ERRORS = 0x8, 29 BASE_SET_DEVICE_PERMISSIONS = 0x9, 30 BASE_SET_PROTOCOL_PERMISSIONS = 0xa, 31 BASE_RESET_AGENT_CONFIGURATION = 0xb, 32 }; 33 34 struct scmi_msg_resp_base_attributes { 35 u8 num_protocols; 36 u8 num_agents; 37 __le16 reserved; 38 }; 39 40 struct scmi_msg_resp_base_discover_agent { 41 __le32 agent_id; 42 u8 name[SCMI_SHORT_NAME_MAX_SIZE]; 43 }; 44 45 46 struct scmi_msg_base_error_notify { 47 __le32 event_control; 48 #define BASE_TP_NOTIFY_ALL BIT(0) 49 }; 50 51 struct scmi_base_error_notify_payld { 52 __le32 agent_id; 53 __le32 error_status; 54 #define IS_FATAL_ERROR(x) ((x) & BIT(31)) 55 #define ERROR_CMD_COUNT(x) FIELD_GET(GENMASK(9, 0), (x)) 56 __le64 msg_reports[SCMI_BASE_MAX_CMD_ERR_COUNT]; 57 }; 58 59 /** 60 * scmi_base_attributes_get() - gets the implementation details 61 * that are associated with the base protocol. 62 * 63 * @ph: SCMI protocol handle 64 * 65 * Return: 0 on success, else appropriate SCMI error. 66 */ 67 static int scmi_base_attributes_get(const struct scmi_protocol_handle *ph) 68 { 69 int ret; 70 struct scmi_xfer *t; 71 struct scmi_msg_resp_base_attributes *attr_info; 72 struct scmi_revision_info *rev = ph->get_priv(ph); 73 74 ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 75 0, sizeof(*attr_info), &t); 76 if (ret) 77 return ret; 78 79 ret = ph->xops->do_xfer(ph, t); 80 if (!ret) { 81 attr_info = t->rx.buf; 82 rev->num_protocols = attr_info->num_protocols; 83 rev->num_agents = attr_info->num_agents; 84 } 85 86 ph->xops->xfer_put(ph, t); 87 88 return ret; 89 } 90 91 /** 92 * scmi_base_vendor_id_get() - gets vendor/subvendor identifier ASCII string. 93 * 94 * @ph: SCMI protocol handle 95 * @sub_vendor: specify true if sub-vendor ID is needed 96 * 97 * Return: 0 on success, else appropriate SCMI error. 98 */ 99 static int 100 scmi_base_vendor_id_get(const struct scmi_protocol_handle *ph, bool sub_vendor) 101 { 102 u8 cmd; 103 int ret, size; 104 char *vendor_id; 105 struct scmi_xfer *t; 106 struct scmi_revision_info *rev = ph->get_priv(ph); 107 108 109 if (sub_vendor) { 110 cmd = BASE_DISCOVER_SUB_VENDOR; 111 vendor_id = rev->sub_vendor_id; 112 size = ARRAY_SIZE(rev->sub_vendor_id); 113 } else { 114 cmd = BASE_DISCOVER_VENDOR; 115 vendor_id = rev->vendor_id; 116 size = ARRAY_SIZE(rev->vendor_id); 117 } 118 119 ret = ph->xops->xfer_get_init(ph, cmd, 0, size, &t); 120 if (ret) 121 return ret; 122 123 ret = ph->xops->do_xfer(ph, t); 124 if (!ret) 125 strscpy(vendor_id, t->rx.buf, size); 126 127 ph->xops->xfer_put(ph, t); 128 129 return ret; 130 } 131 132 /** 133 * scmi_base_implementation_version_get() - gets a vendor-specific 134 * implementation 32-bit version. The format of the version number is 135 * vendor-specific 136 * 137 * @ph: SCMI protocol handle 138 * 139 * Return: 0 on success, else appropriate SCMI error. 140 */ 141 static int 142 scmi_base_implementation_version_get(const struct scmi_protocol_handle *ph) 143 { 144 int ret; 145 __le32 *impl_ver; 146 struct scmi_xfer *t; 147 struct scmi_revision_info *rev = ph->get_priv(ph); 148 149 ret = ph->xops->xfer_get_init(ph, BASE_DISCOVER_IMPLEMENT_VERSION, 150 0, sizeof(*impl_ver), &t); 151 if (ret) 152 return ret; 153 154 ret = ph->xops->do_xfer(ph, t); 155 if (!ret) { 156 impl_ver = t->rx.buf; 157 rev->impl_ver = le32_to_cpu(*impl_ver); 158 } 159 160 ph->xops->xfer_put(ph, t); 161 162 return ret; 163 } 164 165 /** 166 * scmi_base_implementation_list_get() - gets the list of protocols it is 167 * OSPM is allowed to access 168 * 169 * @ph: SCMI protocol handle 170 * @protocols_imp: pointer to hold the list of protocol identifiers 171 * 172 * Return: 0 on success, else appropriate SCMI error. 173 */ 174 static int 175 scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph, 176 u8 *protocols_imp) 177 { 178 u8 *list; 179 int ret, loop; 180 struct scmi_xfer *t; 181 __le32 *num_skip, *num_ret; 182 u32 tot_num_ret = 0, loop_num_ret; 183 struct device *dev = ph->dev; 184 struct scmi_revision_info *rev = ph->get_priv(ph); 185 186 ret = ph->xops->xfer_get_init(ph, BASE_DISCOVER_LIST_PROTOCOLS, 187 sizeof(*num_skip), 0, &t); 188 if (ret) 189 return ret; 190 191 num_skip = t->tx.buf; 192 num_ret = t->rx.buf; 193 list = t->rx.buf + sizeof(*num_ret); 194 195 do { 196 size_t real_list_sz; 197 u32 calc_list_sz; 198 199 /* Set the number of protocols to be skipped/already read */ 200 *num_skip = cpu_to_le32(tot_num_ret); 201 202 ret = ph->xops->do_xfer(ph, t); 203 if (ret) 204 break; 205 206 loop_num_ret = le32_to_cpu(*num_ret); 207 if (!loop_num_ret) 208 break; 209 210 if (loop_num_ret > rev->num_protocols - tot_num_ret) { 211 dev_err(dev, 212 "No. Returned protocols > Total protocols.\n"); 213 break; 214 } 215 216 if (t->rx.len < (sizeof(u32) * 2)) { 217 dev_err(dev, "Truncated reply - rx.len:%zd\n", 218 t->rx.len); 219 ret = -EPROTO; 220 break; 221 } 222 223 real_list_sz = t->rx.len - sizeof(u32); 224 calc_list_sz = (1 + (loop_num_ret - 1) / sizeof(u32)) * 225 sizeof(u32); 226 if (calc_list_sz != real_list_sz) { 227 dev_warn(dev, 228 "Malformed reply - real_sz:%zd calc_sz:%u (loop_num_ret:%d)\n", 229 real_list_sz, calc_list_sz, loop_num_ret); 230 /* 231 * Bail out if the expected list size is bigger than the 232 * total payload size of the received reply. 233 */ 234 if (calc_list_sz > real_list_sz) { 235 ret = -EPROTO; 236 break; 237 } 238 } 239 240 for (loop = 0; loop < loop_num_ret; loop++) 241 protocols_imp[tot_num_ret + loop] = *(list + loop); 242 243 tot_num_ret += loop_num_ret; 244 245 ph->xops->reset_rx_to_maxsz(ph, t); 246 } while (tot_num_ret < rev->num_protocols); 247 248 ph->xops->xfer_put(ph, t); 249 250 return ret; 251 } 252 253 /** 254 * scmi_base_discover_agent_get() - discover the name of an agent 255 * 256 * @ph: SCMI protocol handle 257 * @id: Agent identifier 258 * @name: Agent identifier ASCII string 259 * 260 * An agent id of 0 is reserved to identify the platform itself. 261 * Generally operating system is represented as "OSPM" 262 * 263 * Return: 0 on success, else appropriate SCMI error. 264 */ 265 static int scmi_base_discover_agent_get(const struct scmi_protocol_handle *ph, 266 int id, char *name) 267 { 268 int ret; 269 struct scmi_msg_resp_base_discover_agent *agent_info; 270 struct scmi_xfer *t; 271 272 ret = ph->xops->xfer_get_init(ph, BASE_DISCOVER_AGENT, 273 sizeof(__le32), sizeof(*agent_info), &t); 274 if (ret) 275 return ret; 276 277 put_unaligned_le32(id, t->tx.buf); 278 279 ret = ph->xops->do_xfer(ph, t); 280 if (!ret) { 281 agent_info = t->rx.buf; 282 strscpy(name, agent_info->name, SCMI_SHORT_NAME_MAX_SIZE); 283 } 284 285 ph->xops->xfer_put(ph, t); 286 287 return ret; 288 } 289 290 static int scmi_base_error_notify(const struct scmi_protocol_handle *ph, 291 bool enable) 292 { 293 int ret; 294 u32 evt_cntl = enable ? BASE_TP_NOTIFY_ALL : 0; 295 struct scmi_xfer *t; 296 struct scmi_msg_base_error_notify *cfg; 297 298 ret = ph->xops->xfer_get_init(ph, BASE_NOTIFY_ERRORS, 299 sizeof(*cfg), 0, &t); 300 if (ret) 301 return ret; 302 303 cfg = t->tx.buf; 304 cfg->event_control = cpu_to_le32(evt_cntl); 305 306 ret = ph->xops->do_xfer(ph, t); 307 308 ph->xops->xfer_put(ph, t); 309 return ret; 310 } 311 312 static int scmi_base_set_notify_enabled(const struct scmi_protocol_handle *ph, 313 u8 evt_id, u32 src_id, bool enable) 314 { 315 int ret; 316 317 ret = scmi_base_error_notify(ph, enable); 318 if (ret) 319 pr_debug("FAIL_ENABLED - evt[%X] ret:%d\n", evt_id, ret); 320 321 return ret; 322 } 323 324 static void *scmi_base_fill_custom_report(const struct scmi_protocol_handle *ph, 325 u8 evt_id, ktime_t timestamp, 326 const void *payld, size_t payld_sz, 327 void *report, u32 *src_id) 328 { 329 int i; 330 const struct scmi_base_error_notify_payld *p = payld; 331 struct scmi_base_error_report *r = report; 332 333 /* 334 * BaseError notification payload is variable in size but 335 * up to a maximum length determined by the struct ponted by p. 336 * Instead payld_sz is the effective length of this notification 337 * payload so cannot be greater of the maximum allowed size as 338 * pointed by p. 339 */ 340 if (evt_id != SCMI_EVENT_BASE_ERROR_EVENT || sizeof(*p) < payld_sz) 341 return NULL; 342 343 r->timestamp = timestamp; 344 r->agent_id = le32_to_cpu(p->agent_id); 345 r->fatal = IS_FATAL_ERROR(le32_to_cpu(p->error_status)); 346 r->cmd_count = ERROR_CMD_COUNT(le32_to_cpu(p->error_status)); 347 for (i = 0; i < r->cmd_count; i++) 348 r->reports[i] = le64_to_cpu(p->msg_reports[i]); 349 *src_id = 0; 350 351 return r; 352 } 353 354 static const struct scmi_event base_events[] = { 355 { 356 .id = SCMI_EVENT_BASE_ERROR_EVENT, 357 .max_payld_sz = sizeof(struct scmi_base_error_notify_payld), 358 .max_report_sz = sizeof(struct scmi_base_error_report) + 359 SCMI_BASE_MAX_CMD_ERR_COUNT * sizeof(u64), 360 }, 361 }; 362 363 static const struct scmi_event_ops base_event_ops = { 364 .set_notify_enabled = scmi_base_set_notify_enabled, 365 .fill_custom_report = scmi_base_fill_custom_report, 366 }; 367 368 static const struct scmi_protocol_events base_protocol_events = { 369 .queue_sz = 4 * SCMI_PROTO_QUEUE_SZ, 370 .ops = &base_event_ops, 371 .evts = base_events, 372 .num_events = ARRAY_SIZE(base_events), 373 .num_sources = SCMI_BASE_NUM_SOURCES, 374 }; 375 376 static int scmi_base_protocol_init(const struct scmi_protocol_handle *ph) 377 { 378 int id, ret; 379 u8 *prot_imp; 380 u32 version; 381 char name[SCMI_SHORT_NAME_MAX_SIZE]; 382 struct device *dev = ph->dev; 383 struct scmi_revision_info *rev = scmi_revision_area_get(ph); 384 385 ret = ph->xops->version_get(ph, &version); 386 if (ret) 387 return ret; 388 389 rev->major_ver = PROTOCOL_REV_MAJOR(version), 390 rev->minor_ver = PROTOCOL_REV_MINOR(version); 391 ph->set_priv(ph, rev, version); 392 393 ret = scmi_base_attributes_get(ph); 394 if (ret) 395 return ret; 396 397 prot_imp = devm_kcalloc(dev, rev->num_protocols, sizeof(u8), 398 GFP_KERNEL); 399 if (!prot_imp) 400 return -ENOMEM; 401 402 scmi_base_vendor_id_get(ph, false); 403 scmi_base_vendor_id_get(ph, true); 404 scmi_base_implementation_version_get(ph); 405 scmi_base_implementation_list_get(ph, prot_imp); 406 407 scmi_setup_protocol_implemented(ph, prot_imp); 408 409 dev_info(dev, "SCMI Protocol v%d.%d '%s:%s' Firmware version 0x%x\n", 410 rev->major_ver, rev->minor_ver, rev->vendor_id, 411 rev->sub_vendor_id, rev->impl_ver); 412 dev_dbg(dev, "Found %d protocol(s) %d agent(s)\n", rev->num_protocols, 413 rev->num_agents); 414 415 for (id = 0; id < rev->num_agents; id++) { 416 scmi_base_discover_agent_get(ph, id, name); 417 dev_dbg(dev, "Agent %d: %s\n", id, name); 418 } 419 420 return 0; 421 } 422 423 static const struct scmi_protocol scmi_base = { 424 .id = SCMI_PROTOCOL_BASE, 425 .owner = NULL, 426 .instance_init = &scmi_base_protocol_init, 427 .ops = NULL, 428 .events = &base_protocol_events, 429 .supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION, 430 }; 431 432 DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(base, scmi_base) 433