1 // SPDX-License-Identifier: GPL-2.0
3 * Greybus Firmware Management Protocol Driver.
5 * Copyright 2016 Google Inc.
6 * Copyright 2016 Linaro Ltd.
9 #include <linux/cdev.h>
10 #include <linux/completion.h>
11 #include <linux/firmware.h>
13 #include <linux/idr.h>
14 #include <linux/ioctl.h>
15 #include <linux/uaccess.h>
16 #include <linux/greybus.h>
19 #include "greybus_firmware.h"
21 #define FW_MGMT_TIMEOUT_MS 1000
24 struct device *parent;
25 struct gb_connection *connection;
27 struct list_head node;
29 /* Common id-map for interface and backend firmware requests */
32 struct completion completion;
34 struct device *class_device;
36 unsigned int timeout_jiffies;
37 bool disabled; /* connection getting disabled */
39 /* Interface Firmware specific fields */
40 bool mode_switch_started;
42 u8 intf_fw_request_id;
47 /* Backend Firmware specific fields */
48 u8 backend_fw_request_id;
53 * Number of minor devices this driver supports.
54 * There will be exactly one required per Interface.
56 #define NUM_MINORS U8_MAX
58 static const struct class fw_mgmt_class = {
62 static dev_t fw_mgmt_dev_num;
63 static DEFINE_IDA(fw_mgmt_minors_map);
64 static LIST_HEAD(fw_mgmt_list);
65 static DEFINE_MUTEX(list_mutex);
67 static void fw_mgmt_kref_release(struct kref *kref)
69 struct fw_mgmt *fw_mgmt = container_of(kref, struct fw_mgmt, kref);
71 ida_destroy(&fw_mgmt->id_map);
76 * All users of fw_mgmt take a reference (from within list_mutex lock), before
77 * they get a pointer to play with. And the structure will be freed only after
78 * the last user has put the reference to it.
80 static void put_fw_mgmt(struct fw_mgmt *fw_mgmt)
82 kref_put(&fw_mgmt->kref, fw_mgmt_kref_release);
85 /* Caller must call put_fw_mgmt() after using struct fw_mgmt */
86 static struct fw_mgmt *get_fw_mgmt(struct cdev *cdev)
88 struct fw_mgmt *fw_mgmt;
90 mutex_lock(&list_mutex);
92 list_for_each_entry(fw_mgmt, &fw_mgmt_list, node) {
93 if (&fw_mgmt->cdev == cdev) {
94 kref_get(&fw_mgmt->kref);
102 mutex_unlock(&list_mutex);
107 static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt *fw_mgmt,
108 struct fw_mgmt_ioc_get_intf_version *fw_info)
110 struct gb_connection *connection = fw_mgmt->connection;
111 struct gb_fw_mgmt_interface_fw_version_response response;
114 ret = gb_operation_sync(connection,
115 GB_FW_MGMT_TYPE_INTERFACE_FW_VERSION, NULL, 0,
116 &response, sizeof(response));
118 dev_err(fw_mgmt->parent,
119 "failed to get interface firmware version (%d)\n", ret);
123 fw_info->major = le16_to_cpu(response.major);
124 fw_info->minor = le16_to_cpu(response.minor);
126 strncpy(fw_info->firmware_tag, response.firmware_tag,
127 GB_FIRMWARE_TAG_MAX_SIZE);
130 * The firmware-tag should be NULL terminated, otherwise throw error but
133 if (fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
134 dev_err(fw_mgmt->parent,
135 "fw-version: firmware-tag is not NULL terminated\n");
136 fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] = '\0';
142 static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt,
143 u8 load_method, const char *tag)
145 struct gb_fw_mgmt_load_and_validate_fw_request request;
148 if (load_method != GB_FW_LOAD_METHOD_UNIPRO &&
149 load_method != GB_FW_LOAD_METHOD_INTERNAL) {
150 dev_err(fw_mgmt->parent,
151 "invalid load-method (%d)\n", load_method);
155 request.load_method = load_method;
156 strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
159 * The firmware-tag should be NULL terminated, otherwise throw error and
162 if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
163 dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n");
167 /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
168 ret = ida_alloc_range(&fw_mgmt->id_map, 1, 255, GFP_KERNEL);
170 dev_err(fw_mgmt->parent, "failed to allocate request id (%d)\n",
175 fw_mgmt->intf_fw_request_id = ret;
176 fw_mgmt->intf_fw_loaded = false;
177 request.request_id = ret;
179 ret = gb_operation_sync(fw_mgmt->connection,
180 GB_FW_MGMT_TYPE_LOAD_AND_VALIDATE_FW, &request,
181 sizeof(request), NULL, 0);
183 ida_free(&fw_mgmt->id_map, fw_mgmt->intf_fw_request_id);
184 fw_mgmt->intf_fw_request_id = 0;
185 dev_err(fw_mgmt->parent,
186 "load and validate firmware request failed (%d)\n",
194 static int fw_mgmt_interface_fw_loaded_operation(struct gb_operation *op)
196 struct gb_connection *connection = op->connection;
197 struct fw_mgmt *fw_mgmt = gb_connection_get_data(connection);
198 struct gb_fw_mgmt_loaded_fw_request *request;
200 /* No pending load and validate request ? */
201 if (!fw_mgmt->intf_fw_request_id) {
202 dev_err(fw_mgmt->parent,
203 "unexpected firmware loaded request received\n");
207 if (op->request->payload_size != sizeof(*request)) {
208 dev_err(fw_mgmt->parent, "illegal size of firmware loaded request (%zu != %zu)\n",
209 op->request->payload_size, sizeof(*request));
213 request = op->request->payload;
215 /* Invalid request-id ? */
216 if (request->request_id != fw_mgmt->intf_fw_request_id) {
217 dev_err(fw_mgmt->parent, "invalid request id for firmware loaded request (%02u != %02u)\n",
218 fw_mgmt->intf_fw_request_id, request->request_id);
222 ida_free(&fw_mgmt->id_map, fw_mgmt->intf_fw_request_id);
223 fw_mgmt->intf_fw_request_id = 0;
224 fw_mgmt->intf_fw_status = request->status;
225 fw_mgmt->intf_fw_major = le16_to_cpu(request->major);
226 fw_mgmt->intf_fw_minor = le16_to_cpu(request->minor);
228 if (fw_mgmt->intf_fw_status == GB_FW_LOAD_STATUS_FAILED)
229 dev_err(fw_mgmt->parent,
230 "failed to load interface firmware, status:%02x\n",
231 fw_mgmt->intf_fw_status);
232 else if (fw_mgmt->intf_fw_status == GB_FW_LOAD_STATUS_VALIDATION_FAILED)
233 dev_err(fw_mgmt->parent,
234 "failed to validate interface firmware, status:%02x\n",
235 fw_mgmt->intf_fw_status);
237 fw_mgmt->intf_fw_loaded = true;
239 complete(&fw_mgmt->completion);
244 static int fw_mgmt_backend_fw_version_operation(struct fw_mgmt *fw_mgmt,
245 struct fw_mgmt_ioc_get_backend_version *fw_info)
247 struct gb_connection *connection = fw_mgmt->connection;
248 struct gb_fw_mgmt_backend_fw_version_request request;
249 struct gb_fw_mgmt_backend_fw_version_response response;
252 strncpy(request.firmware_tag, fw_info->firmware_tag,
253 GB_FIRMWARE_TAG_MAX_SIZE);
256 * The firmware-tag should be NULL terminated, otherwise throw error and
259 if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
260 dev_err(fw_mgmt->parent, "backend-version: firmware-tag is not NULL terminated\n");
264 ret = gb_operation_sync(connection,
265 GB_FW_MGMT_TYPE_BACKEND_FW_VERSION, &request,
266 sizeof(request), &response, sizeof(response));
268 dev_err(fw_mgmt->parent, "failed to get version of %s backend firmware (%d)\n",
269 fw_info->firmware_tag, ret);
273 fw_info->status = response.status;
275 /* Reset version as that should be non-zero only for success case */
279 switch (fw_info->status) {
280 case GB_FW_BACKEND_VERSION_STATUS_SUCCESS:
281 fw_info->major = le16_to_cpu(response.major);
282 fw_info->minor = le16_to_cpu(response.minor);
284 case GB_FW_BACKEND_VERSION_STATUS_NOT_AVAILABLE:
285 case GB_FW_BACKEND_VERSION_STATUS_RETRY:
287 case GB_FW_BACKEND_VERSION_STATUS_NOT_SUPPORTED:
288 dev_err(fw_mgmt->parent,
289 "Firmware with tag %s is not supported by Interface\n",
290 fw_info->firmware_tag);
293 dev_err(fw_mgmt->parent, "Invalid status received: %u\n",
300 static int fw_mgmt_backend_fw_update_operation(struct fw_mgmt *fw_mgmt,
303 struct gb_fw_mgmt_backend_fw_update_request request;
306 strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
309 * The firmware-tag should be NULL terminated, otherwise throw error and
312 if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
313 dev_err(fw_mgmt->parent, "backend-update: firmware-tag is not NULL terminated\n");
317 /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
318 ret = ida_alloc_range(&fw_mgmt->id_map, 1, 255, GFP_KERNEL);
320 dev_err(fw_mgmt->parent, "failed to allocate request id (%d)\n",
325 fw_mgmt->backend_fw_request_id = ret;
326 request.request_id = ret;
328 ret = gb_operation_sync(fw_mgmt->connection,
329 GB_FW_MGMT_TYPE_BACKEND_FW_UPDATE, &request,
330 sizeof(request), NULL, 0);
332 ida_free(&fw_mgmt->id_map, fw_mgmt->backend_fw_request_id);
333 fw_mgmt->backend_fw_request_id = 0;
334 dev_err(fw_mgmt->parent,
335 "backend %s firmware update request failed (%d)\n", tag,
343 static int fw_mgmt_backend_fw_updated_operation(struct gb_operation *op)
345 struct gb_connection *connection = op->connection;
346 struct fw_mgmt *fw_mgmt = gb_connection_get_data(connection);
347 struct gb_fw_mgmt_backend_fw_updated_request *request;
349 /* No pending load and validate request ? */
350 if (!fw_mgmt->backend_fw_request_id) {
351 dev_err(fw_mgmt->parent, "unexpected backend firmware updated request received\n");
355 if (op->request->payload_size != sizeof(*request)) {
356 dev_err(fw_mgmt->parent, "illegal size of backend firmware updated request (%zu != %zu)\n",
357 op->request->payload_size, sizeof(*request));
361 request = op->request->payload;
363 /* Invalid request-id ? */
364 if (request->request_id != fw_mgmt->backend_fw_request_id) {
365 dev_err(fw_mgmt->parent, "invalid request id for backend firmware updated request (%02u != %02u)\n",
366 fw_mgmt->backend_fw_request_id, request->request_id);
370 ida_free(&fw_mgmt->id_map, fw_mgmt->backend_fw_request_id);
371 fw_mgmt->backend_fw_request_id = 0;
372 fw_mgmt->backend_fw_status = request->status;
374 if ((fw_mgmt->backend_fw_status != GB_FW_BACKEND_FW_STATUS_SUCCESS) &&
375 (fw_mgmt->backend_fw_status != GB_FW_BACKEND_FW_STATUS_RETRY))
376 dev_err(fw_mgmt->parent,
377 "failed to load backend firmware: %02x\n",
378 fw_mgmt->backend_fw_status);
380 complete(&fw_mgmt->completion);
385 /* Char device fops */
387 static int fw_mgmt_open(struct inode *inode, struct file *file)
389 struct fw_mgmt *fw_mgmt = get_fw_mgmt(inode->i_cdev);
391 /* fw_mgmt structure can't get freed until file descriptor is closed */
393 file->private_data = fw_mgmt;
400 static int fw_mgmt_release(struct inode *inode, struct file *file)
402 struct fw_mgmt *fw_mgmt = file->private_data;
404 put_fw_mgmt(fw_mgmt);
408 static int fw_mgmt_ioctl(struct fw_mgmt *fw_mgmt, unsigned int cmd,
411 struct fw_mgmt_ioc_get_intf_version intf_fw_info;
412 struct fw_mgmt_ioc_get_backend_version backend_fw_info;
413 struct fw_mgmt_ioc_intf_load_and_validate intf_load;
414 struct fw_mgmt_ioc_backend_fw_update backend_update;
415 unsigned int timeout;
418 /* Reject any operations after mode-switch has started */
419 if (fw_mgmt->mode_switch_started)
423 case FW_MGMT_IOC_GET_INTF_FW:
424 ret = fw_mgmt_interface_fw_version_operation(fw_mgmt,
429 if (copy_to_user(buf, &intf_fw_info, sizeof(intf_fw_info)))
433 case FW_MGMT_IOC_GET_BACKEND_FW:
434 if (copy_from_user(&backend_fw_info, buf,
435 sizeof(backend_fw_info)))
438 ret = fw_mgmt_backend_fw_version_operation(fw_mgmt,
443 if (copy_to_user(buf, &backend_fw_info,
444 sizeof(backend_fw_info)))
448 case FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE:
449 if (copy_from_user(&intf_load, buf, sizeof(intf_load)))
452 ret = fw_mgmt_load_and_validate_operation(fw_mgmt,
453 intf_load.load_method, intf_load.firmware_tag);
457 if (!wait_for_completion_timeout(&fw_mgmt->completion,
458 fw_mgmt->timeout_jiffies)) {
459 dev_err(fw_mgmt->parent, "timed out waiting for firmware load and validation to finish\n");
463 intf_load.status = fw_mgmt->intf_fw_status;
464 intf_load.major = fw_mgmt->intf_fw_major;
465 intf_load.minor = fw_mgmt->intf_fw_minor;
467 if (copy_to_user(buf, &intf_load, sizeof(intf_load)))
471 case FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE:
472 if (copy_from_user(&backend_update, buf,
473 sizeof(backend_update)))
476 ret = fw_mgmt_backend_fw_update_operation(fw_mgmt,
477 backend_update.firmware_tag);
481 if (!wait_for_completion_timeout(&fw_mgmt->completion,
482 fw_mgmt->timeout_jiffies)) {
483 dev_err(fw_mgmt->parent, "timed out waiting for backend firmware update to finish\n");
487 backend_update.status = fw_mgmt->backend_fw_status;
489 if (copy_to_user(buf, &backend_update, sizeof(backend_update)))
493 case FW_MGMT_IOC_SET_TIMEOUT_MS:
494 if (get_user(timeout, (unsigned int __user *)buf))
498 dev_err(fw_mgmt->parent, "timeout can't be zero\n");
502 fw_mgmt->timeout_jiffies = msecs_to_jiffies(timeout);
505 case FW_MGMT_IOC_MODE_SWITCH:
506 if (!fw_mgmt->intf_fw_loaded) {
507 dev_err(fw_mgmt->parent,
508 "Firmware not loaded for mode-switch\n");
513 * Disallow new ioctls as the fw-core bundle driver is going to
514 * get disconnected soon and the character device will get
517 fw_mgmt->mode_switch_started = true;
519 ret = gb_interface_request_mode_switch(fw_mgmt->connection->intf);
521 dev_err(fw_mgmt->parent, "Mode-switch failed: %d\n",
523 fw_mgmt->mode_switch_started = false;
533 static long fw_mgmt_ioctl_unlocked(struct file *file, unsigned int cmd,
536 struct fw_mgmt *fw_mgmt = file->private_data;
537 struct gb_bundle *bundle = fw_mgmt->connection->bundle;
543 * We don't want the user to do few operations in parallel. For example,
544 * updating Interface firmware in parallel for the same Interface. There
545 * is no need to do things in parallel for speed and we can avoid having
546 * complicated code for now.
548 * This is also used to protect ->disabled, which is used to check if
549 * the connection is getting disconnected, so that we don't start any
552 mutex_lock(&fw_mgmt->mutex);
553 if (!fw_mgmt->disabled) {
554 ret = gb_pm_runtime_get_sync(bundle);
556 ret = fw_mgmt_ioctl(fw_mgmt, cmd, (void __user *)arg);
557 gb_pm_runtime_put_autosuspend(bundle);
560 mutex_unlock(&fw_mgmt->mutex);
565 static const struct file_operations fw_mgmt_fops = {
566 .owner = THIS_MODULE,
567 .open = fw_mgmt_open,
568 .release = fw_mgmt_release,
569 .unlocked_ioctl = fw_mgmt_ioctl_unlocked,
572 int gb_fw_mgmt_request_handler(struct gb_operation *op)
577 case GB_FW_MGMT_TYPE_LOADED_FW:
578 return fw_mgmt_interface_fw_loaded_operation(op);
579 case GB_FW_MGMT_TYPE_BACKEND_FW_UPDATED:
580 return fw_mgmt_backend_fw_updated_operation(op);
582 dev_err(&op->connection->bundle->dev,
583 "unsupported request: %u\n", type);
588 int gb_fw_mgmt_connection_init(struct gb_connection *connection)
590 struct fw_mgmt *fw_mgmt;
596 fw_mgmt = kzalloc(sizeof(*fw_mgmt), GFP_KERNEL);
600 fw_mgmt->parent = &connection->bundle->dev;
601 fw_mgmt->timeout_jiffies = msecs_to_jiffies(FW_MGMT_TIMEOUT_MS);
602 fw_mgmt->connection = connection;
604 gb_connection_set_data(connection, fw_mgmt);
605 init_completion(&fw_mgmt->completion);
606 ida_init(&fw_mgmt->id_map);
607 mutex_init(&fw_mgmt->mutex);
608 kref_init(&fw_mgmt->kref);
610 mutex_lock(&list_mutex);
611 list_add(&fw_mgmt->node, &fw_mgmt_list);
612 mutex_unlock(&list_mutex);
614 ret = gb_connection_enable(connection);
618 minor = ida_alloc_max(&fw_mgmt_minors_map, NUM_MINORS - 1, GFP_KERNEL);
621 goto err_connection_disable;
624 /* Add a char device to allow userspace to interact with fw-mgmt */
625 fw_mgmt->dev_num = MKDEV(MAJOR(fw_mgmt_dev_num), minor);
626 cdev_init(&fw_mgmt->cdev, &fw_mgmt_fops);
628 ret = cdev_add(&fw_mgmt->cdev, fw_mgmt->dev_num, 1);
632 /* Add a soft link to the previously added char-dev within the bundle */
633 fw_mgmt->class_device = device_create(&fw_mgmt_class, fw_mgmt->parent,
634 fw_mgmt->dev_num, NULL,
635 "gb-fw-mgmt-%d", minor);
636 if (IS_ERR(fw_mgmt->class_device)) {
637 ret = PTR_ERR(fw_mgmt->class_device);
644 cdev_del(&fw_mgmt->cdev);
646 ida_free(&fw_mgmt_minors_map, minor);
647 err_connection_disable:
648 gb_connection_disable(connection);
650 mutex_lock(&list_mutex);
651 list_del(&fw_mgmt->node);
652 mutex_unlock(&list_mutex);
654 put_fw_mgmt(fw_mgmt);
659 void gb_fw_mgmt_connection_exit(struct gb_connection *connection)
661 struct fw_mgmt *fw_mgmt;
666 fw_mgmt = gb_connection_get_data(connection);
668 device_destroy(&fw_mgmt_class, fw_mgmt->dev_num);
669 cdev_del(&fw_mgmt->cdev);
670 ida_free(&fw_mgmt_minors_map, MINOR(fw_mgmt->dev_num));
673 * Disallow any new ioctl operations on the char device and wait for
674 * existing ones to finish.
676 mutex_lock(&fw_mgmt->mutex);
677 fw_mgmt->disabled = true;
678 mutex_unlock(&fw_mgmt->mutex);
680 /* All pending greybus operations should have finished by now */
681 gb_connection_disable(fw_mgmt->connection);
683 /* Disallow new users to get access to the fw_mgmt structure */
684 mutex_lock(&list_mutex);
685 list_del(&fw_mgmt->node);
686 mutex_unlock(&list_mutex);
689 * All current users of fw_mgmt would have taken a reference to it by
690 * now, we can drop our reference and wait the last user will get
693 put_fw_mgmt(fw_mgmt);
696 int fw_mgmt_init(void)
700 ret = class_register(&fw_mgmt_class);
704 ret = alloc_chrdev_region(&fw_mgmt_dev_num, 0, NUM_MINORS,
707 goto err_remove_class;
712 class_unregister(&fw_mgmt_class);
716 void fw_mgmt_exit(void)
718 unregister_chrdev_region(fw_mgmt_dev_num, NUM_MINORS);
719 class_unregister(&fw_mgmt_class);
720 ida_destroy(&fw_mgmt_minors_map);