2 * Greybus Firmware Management Protocol Driver.
4 * Copyright 2016 Google Inc.
5 * Copyright 2016 Linaro Ltd.
7 * Released under the GPLv2 only.
10 #include <linux/cdev.h>
11 #include <linux/completion.h>
12 #include <linux/firmware.h>
14 #include <linux/idr.h>
15 #include <linux/ioctl.h>
16 #include <linux/uaccess.h>
19 #include "greybus_firmware.h"
22 #define FW_MGMT_TIMEOUT_MS 1000
25 struct device
*parent
;
26 struct gb_connection
*connection
;
28 struct list_head node
;
30 /* Common id-map for interface and backend firmware requests */
33 struct completion completion
;
35 struct device
*class_device
;
37 unsigned int timeout_jiffies
;
38 bool disabled
; /* connection getting disabled */
40 /* Interface Firmware specific fields */
41 bool mode_switch_started
;
43 u8 intf_fw_request_id
;
48 /* Backend Firmware specific fields */
49 u8 backend_fw_request_id
;
54 * Number of minor devices this driver supports.
55 * There will be exactly one required per Interface.
57 #define NUM_MINORS U8_MAX
59 static struct class *fw_mgmt_class
;
60 static dev_t fw_mgmt_dev_num
;
61 static DEFINE_IDA(fw_mgmt_minors_map
);
62 static LIST_HEAD(fw_mgmt_list
);
63 static DEFINE_MUTEX(list_mutex
);
65 static void fw_mgmt_kref_release(struct kref
*kref
)
67 struct fw_mgmt
*fw_mgmt
= container_of(kref
, struct fw_mgmt
, kref
);
69 ida_destroy(&fw_mgmt
->id_map
);
74 * All users of fw_mgmt take a reference (from within list_mutex lock), before
75 * they get a pointer to play with. And the structure will be freed only after
76 * the last user has put the reference to it.
78 static void put_fw_mgmt(struct fw_mgmt
*fw_mgmt
)
80 kref_put(&fw_mgmt
->kref
, fw_mgmt_kref_release
);
83 /* Caller must call put_fw_mgmt() after using struct fw_mgmt */
84 static struct fw_mgmt
*get_fw_mgmt(struct cdev
*cdev
)
86 struct fw_mgmt
*fw_mgmt
;
88 mutex_lock(&list_mutex
);
90 list_for_each_entry(fw_mgmt
, &fw_mgmt_list
, node
) {
91 if (&fw_mgmt
->cdev
== cdev
) {
92 kref_get(&fw_mgmt
->kref
);
100 mutex_unlock(&list_mutex
);
105 static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt
*fw_mgmt
,
106 struct fw_mgmt_ioc_get_intf_version
*fw_info
)
108 struct gb_connection
*connection
= fw_mgmt
->connection
;
109 struct gb_fw_mgmt_interface_fw_version_response response
;
112 ret
= gb_operation_sync(connection
,
113 GB_FW_MGMT_TYPE_INTERFACE_FW_VERSION
, NULL
, 0,
114 &response
, sizeof(response
));
116 dev_err(fw_mgmt
->parent
,
117 "failed to get interface firmware version (%d)\n", ret
);
121 fw_info
->major
= le16_to_cpu(response
.major
);
122 fw_info
->minor
= le16_to_cpu(response
.minor
);
124 strncpy(fw_info
->firmware_tag
, response
.firmware_tag
,
125 GB_FIRMWARE_TAG_MAX_SIZE
);
128 * The firmware-tag should be NULL terminated, otherwise throw error but
131 if (fw_info
->firmware_tag
[GB_FIRMWARE_TAG_MAX_SIZE
- 1] != '\0') {
132 dev_err(fw_mgmt
->parent
,
133 "fw-version: firmware-tag is not NULL terminated\n");
134 fw_info
->firmware_tag
[GB_FIRMWARE_TAG_MAX_SIZE
- 1] = '\0';
140 static int fw_mgmt_load_and_validate_operation(struct fw_mgmt
*fw_mgmt
,
141 u8 load_method
, const char *tag
)
143 struct gb_fw_mgmt_load_and_validate_fw_request request
;
146 if (load_method
!= GB_FW_LOAD_METHOD_UNIPRO
&&
147 load_method
!= GB_FW_LOAD_METHOD_INTERNAL
) {
148 dev_err(fw_mgmt
->parent
,
149 "invalid load-method (%d)\n", load_method
);
153 request
.load_method
= load_method
;
154 strncpy(request
.firmware_tag
, tag
, GB_FIRMWARE_TAG_MAX_SIZE
);
157 * The firmware-tag should be NULL terminated, otherwise throw error and
160 if (request
.firmware_tag
[GB_FIRMWARE_TAG_MAX_SIZE
- 1] != '\0') {
161 dev_err(fw_mgmt
->parent
, "load-and-validate: firmware-tag is not NULL terminated\n");
165 /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
166 ret
= ida_simple_get(&fw_mgmt
->id_map
, 1, 256, GFP_KERNEL
);
168 dev_err(fw_mgmt
->parent
, "failed to allocate request id (%d)\n",
173 fw_mgmt
->intf_fw_request_id
= ret
;
174 fw_mgmt
->intf_fw_loaded
= false;
175 request
.request_id
= ret
;
177 ret
= gb_operation_sync(fw_mgmt
->connection
,
178 GB_FW_MGMT_TYPE_LOAD_AND_VALIDATE_FW
, &request
,
179 sizeof(request
), NULL
, 0);
181 ida_simple_remove(&fw_mgmt
->id_map
,
182 fw_mgmt
->intf_fw_request_id
);
183 fw_mgmt
->intf_fw_request_id
= 0;
184 dev_err(fw_mgmt
->parent
,
185 "load and validate firmware request failed (%d)\n",
193 static int fw_mgmt_interface_fw_loaded_operation(struct gb_operation
*op
)
195 struct gb_connection
*connection
= op
->connection
;
196 struct fw_mgmt
*fw_mgmt
= gb_connection_get_data(connection
);
197 struct gb_fw_mgmt_loaded_fw_request
*request
;
199 /* No pending load and validate request ? */
200 if (!fw_mgmt
->intf_fw_request_id
) {
201 dev_err(fw_mgmt
->parent
,
202 "unexpected firmware loaded request received\n");
206 if (op
->request
->payload_size
!= sizeof(*request
)) {
207 dev_err(fw_mgmt
->parent
, "illegal size of firmware loaded request (%zu != %zu)\n",
208 op
->request
->payload_size
, sizeof(*request
));
212 request
= op
->request
->payload
;
214 /* Invalid request-id ? */
215 if (request
->request_id
!= fw_mgmt
->intf_fw_request_id
) {
216 dev_err(fw_mgmt
->parent
, "invalid request id for firmware loaded request (%02u != %02u)\n",
217 fw_mgmt
->intf_fw_request_id
, request
->request_id
);
221 ida_simple_remove(&fw_mgmt
->id_map
, fw_mgmt
->intf_fw_request_id
);
222 fw_mgmt
->intf_fw_request_id
= 0;
223 fw_mgmt
->intf_fw_status
= request
->status
;
224 fw_mgmt
->intf_fw_major
= le16_to_cpu(request
->major
);
225 fw_mgmt
->intf_fw_minor
= le16_to_cpu(request
->minor
);
227 if (fw_mgmt
->intf_fw_status
== GB_FW_LOAD_STATUS_FAILED
)
228 dev_err(fw_mgmt
->parent
,
229 "failed to load interface firmware, status:%02x\n",
230 fw_mgmt
->intf_fw_status
);
231 else if (fw_mgmt
->intf_fw_status
== GB_FW_LOAD_STATUS_VALIDATION_FAILED
)
232 dev_err(fw_mgmt
->parent
,
233 "failed to validate interface firmware, status:%02x\n",
234 fw_mgmt
->intf_fw_status
);
236 fw_mgmt
->intf_fw_loaded
= true;
238 complete(&fw_mgmt
->completion
);
243 static int fw_mgmt_backend_fw_version_operation(struct fw_mgmt
*fw_mgmt
,
244 struct fw_mgmt_ioc_get_backend_version
*fw_info
)
246 struct gb_connection
*connection
= fw_mgmt
->connection
;
247 struct gb_fw_mgmt_backend_fw_version_request request
;
248 struct gb_fw_mgmt_backend_fw_version_response response
;
251 strncpy(request
.firmware_tag
, fw_info
->firmware_tag
,
252 GB_FIRMWARE_TAG_MAX_SIZE
);
255 * The firmware-tag should be NULL terminated, otherwise throw error and
258 if (request
.firmware_tag
[GB_FIRMWARE_TAG_MAX_SIZE
- 1] != '\0') {
259 dev_err(fw_mgmt
->parent
, "backend-version: firmware-tag is not NULL terminated\n");
263 ret
= gb_operation_sync(connection
,
264 GB_FW_MGMT_TYPE_BACKEND_FW_VERSION
, &request
,
265 sizeof(request
), &response
, sizeof(response
));
267 dev_err(fw_mgmt
->parent
, "failed to get version of %s backend firmware (%d)\n",
268 fw_info
->firmware_tag
, ret
);
272 fw_info
->status
= response
.status
;
274 /* Reset version as that should be non-zero only for success case */
278 switch (fw_info
->status
) {
279 case GB_FW_BACKEND_VERSION_STATUS_SUCCESS
:
280 fw_info
->major
= le16_to_cpu(response
.major
);
281 fw_info
->minor
= le16_to_cpu(response
.minor
);
283 case GB_FW_BACKEND_VERSION_STATUS_NOT_AVAILABLE
:
284 case GB_FW_BACKEND_VERSION_STATUS_RETRY
:
286 case GB_FW_BACKEND_VERSION_STATUS_NOT_SUPPORTED
:
287 dev_err(fw_mgmt
->parent
,
288 "Firmware with tag %s is not supported by Interface\n",
289 fw_info
->firmware_tag
);
292 dev_err(fw_mgmt
->parent
, "Invalid status received: %u\n",
299 static int fw_mgmt_backend_fw_update_operation(struct fw_mgmt
*fw_mgmt
,
302 struct gb_fw_mgmt_backend_fw_update_request request
;
305 strncpy(request
.firmware_tag
, tag
, GB_FIRMWARE_TAG_MAX_SIZE
);
308 * The firmware-tag should be NULL terminated, otherwise throw error and
311 if (request
.firmware_tag
[GB_FIRMWARE_TAG_MAX_SIZE
- 1] != '\0') {
312 dev_err(fw_mgmt
->parent
, "backend-update: firmware-tag is not NULL terminated\n");
316 /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
317 ret
= ida_simple_get(&fw_mgmt
->id_map
, 1, 256, GFP_KERNEL
);
319 dev_err(fw_mgmt
->parent
, "failed to allocate request id (%d)\n",
324 fw_mgmt
->backend_fw_request_id
= ret
;
325 request
.request_id
= ret
;
327 ret
= gb_operation_sync(fw_mgmt
->connection
,
328 GB_FW_MGMT_TYPE_BACKEND_FW_UPDATE
, &request
,
329 sizeof(request
), NULL
, 0);
331 ida_simple_remove(&fw_mgmt
->id_map
,
332 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_simple_remove(&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_simple_get(&fw_mgmt_minors_map
, 0, NUM_MINORS
, 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_simple_remove(&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_simple_remove(&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 fw_mgmt_class
= class_create(THIS_MODULE
, "gb_fw_mgmt");
701 if (IS_ERR(fw_mgmt_class
))
702 return PTR_ERR(fw_mgmt_class
);
704 ret
= alloc_chrdev_region(&fw_mgmt_dev_num
, 0, NUM_MINORS
,
707 goto err_remove_class
;
712 class_destroy(fw_mgmt_class
);
716 void fw_mgmt_exit(void)
718 unregister_chrdev_region(fw_mgmt_dev_num
, NUM_MINORS
);
719 class_destroy(fw_mgmt_class
);
720 ida_destroy(&fw_mgmt_minors_map
);