linux/drivers/staging/greybus/fw-download.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Greybus Firmware Download Protocol Driver.
   4 *
   5 * Copyright 2016 Google Inc.
   6 * Copyright 2016 Linaro Ltd.
   7 */
   8
   9#include <linux/firmware.h>
  10#include <linux/jiffies.h>
  11#include <linux/mutex.h>
  12#include <linux/workqueue.h>
  13#include "firmware.h"
  14#include "greybus.h"
  15
  16/* Estimated minimum buffer size, actual size can be smaller than this */
  17#define MIN_FETCH_SIZE          512
  18/* Timeout, in jiffies, within which fetch or release firmware must be called */
  19#define NEXT_REQ_TIMEOUT_J      msecs_to_jiffies(1000)
  20
  21struct fw_request {
  22        u8                      firmware_id;
  23        bool                    disabled;
  24        bool                    timedout;
  25        char                    name[FW_NAME_SIZE];
  26        const struct firmware   *fw;
  27        struct list_head        node;
  28
  29        struct delayed_work     dwork;
  30        /* Timeout, in jiffies, within which the firmware shall download */
  31        unsigned long           release_timeout_j;
  32        struct kref             kref;
  33        struct fw_download      *fw_download;
  34};
  35
  36struct fw_download {
  37        struct device           *parent;
  38        struct gb_connection    *connection;
  39        struct list_head        fw_requests;
  40        struct ida              id_map;
  41        struct mutex            mutex;
  42};
  43
  44static void fw_req_release(struct kref *kref)
  45{
  46        struct fw_request *fw_req = container_of(kref, struct fw_request, kref);
  47
  48        dev_dbg(fw_req->fw_download->parent, "firmware %s released\n",
  49                fw_req->name);
  50
  51        release_firmware(fw_req->fw);
  52
  53        /*
  54         * The request timed out and the module may send a fetch-fw or
  55         * release-fw request later. Lets block the id we allocated for this
  56         * request, so that the AP doesn't refer to a later fw-request (with
  57         * same firmware_id) for the old timedout fw-request.
  58         *
  59         * NOTE:
  60         *
  61         * This also means that after 255 timeouts we will fail to service new
  62         * firmware downloads. But what else can we do in that case anyway? Lets
  63         * just hope that it never happens.
  64         */
  65        if (!fw_req->timedout)
  66                ida_simple_remove(&fw_req->fw_download->id_map,
  67                                  fw_req->firmware_id);
  68
  69        kfree(fw_req);
  70}
  71
  72/*
  73 * Incoming requests are serialized for a connection, and the only race possible
  74 * is between the timeout handler freeing this and an incoming request.
  75 *
  76 * The operations on the fw-request list are protected by the mutex and
  77 * get_fw_req() increments the reference count before returning a fw_req pointer
  78 * to the users.
  79 *
  80 * free_firmware() also takes the mutex while removing an entry from the list,
  81 * it guarantees that every user of fw_req has taken a kref-reference by now and
  82 * we wouldn't have any new users.
  83 *
  84 * Once the last user drops the reference, the fw_req structure is freed.
  85 */
  86static void put_fw_req(struct fw_request *fw_req)
  87{
  88        kref_put(&fw_req->kref, fw_req_release);
  89}
  90
  91/* Caller must call put_fw_req() after using struct fw_request */
  92static struct fw_request *get_fw_req(struct fw_download *fw_download,
  93                                     u8 firmware_id)
  94{
  95        struct fw_request *fw_req;
  96
  97        mutex_lock(&fw_download->mutex);
  98
  99        list_for_each_entry(fw_req, &fw_download->fw_requests, node) {
 100                if (fw_req->firmware_id == firmware_id) {
 101                        kref_get(&fw_req->kref);
 102                        goto unlock;
 103                }
 104        }
 105
 106        fw_req = NULL;
 107
 108unlock:
 109        mutex_unlock(&fw_download->mutex);
 110
 111        return fw_req;
 112}
 113
 114static void free_firmware(struct fw_download *fw_download,
 115                          struct fw_request *fw_req)
 116{
 117        /* Already disabled from timeout handlers */
 118        if (fw_req->disabled)
 119                return;
 120
 121        mutex_lock(&fw_download->mutex);
 122        list_del(&fw_req->node);
 123        mutex_unlock(&fw_download->mutex);
 124
 125        fw_req->disabled = true;
 126        put_fw_req(fw_req);
 127}
 128
 129static void fw_request_timedout(struct work_struct *work)
 130{
 131        struct delayed_work *dwork = to_delayed_work(work);
 132        struct fw_request *fw_req = container_of(dwork,
 133                                                 struct fw_request, dwork);
 134        struct fw_download *fw_download = fw_req->fw_download;
 135
 136        dev_err(fw_download->parent,
 137                "Timed out waiting for fetch / release firmware requests: %u\n",
 138                fw_req->firmware_id);
 139
 140        fw_req->timedout = true;
 141        free_firmware(fw_download, fw_req);
 142}
 143
 144static int exceeds_release_timeout(struct fw_request *fw_req)
 145{
 146        struct fw_download *fw_download = fw_req->fw_download;
 147
 148        if (time_before(jiffies, fw_req->release_timeout_j))
 149                return 0;
 150
 151        dev_err(fw_download->parent,
 152                "Firmware download didn't finish in time, abort: %d\n",
 153                fw_req->firmware_id);
 154
 155        fw_req->timedout = true;
 156        free_firmware(fw_download, fw_req);
 157
 158        return -ETIMEDOUT;
 159}
 160
 161/* This returns path of the firmware blob on the disk */
 162static struct fw_request *find_firmware(struct fw_download *fw_download,
 163                                        const char *tag)
 164{
 165        struct gb_interface *intf = fw_download->connection->bundle->intf;
 166        struct fw_request *fw_req;
 167        int ret, req_count;
 168
 169        fw_req = kzalloc(sizeof(*fw_req), GFP_KERNEL);
 170        if (!fw_req)
 171                return ERR_PTR(-ENOMEM);
 172
 173        /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
 174        ret = ida_simple_get(&fw_download->id_map, 1, 256, GFP_KERNEL);
 175        if (ret < 0) {
 176                dev_err(fw_download->parent,
 177                        "failed to allocate firmware id (%d)\n", ret);
 178                goto err_free_req;
 179        }
 180        fw_req->firmware_id = ret;
 181
 182        snprintf(fw_req->name, sizeof(fw_req->name),
 183                 FW_NAME_PREFIX "%08x_%08x_%08x_%08x_%s.tftf",
 184                 intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
 185                 intf->vendor_id, intf->product_id, tag);
 186
 187        dev_info(fw_download->parent, "Requested firmware package '%s'\n",
 188                 fw_req->name);
 189
 190        ret = request_firmware(&fw_req->fw, fw_req->name, fw_download->parent);
 191        if (ret) {
 192                dev_err(fw_download->parent,
 193                        "firmware request failed for %s (%d)\n", fw_req->name,
 194                        ret);
 195                goto err_free_id;
 196        }
 197
 198        fw_req->fw_download = fw_download;
 199        kref_init(&fw_req->kref);
 200
 201        mutex_lock(&fw_download->mutex);
 202        list_add(&fw_req->node, &fw_download->fw_requests);
 203        mutex_unlock(&fw_download->mutex);
 204
 205        /* Timeout, in jiffies, within which firmware should get loaded */
 206        req_count = DIV_ROUND_UP(fw_req->fw->size, MIN_FETCH_SIZE);
 207        fw_req->release_timeout_j = jiffies + req_count * NEXT_REQ_TIMEOUT_J;
 208
 209        INIT_DELAYED_WORK(&fw_req->dwork, fw_request_timedout);
 210        schedule_delayed_work(&fw_req->dwork, NEXT_REQ_TIMEOUT_J);
 211
 212        return fw_req;
 213
 214err_free_id:
 215        ida_simple_remove(&fw_download->id_map, fw_req->firmware_id);
 216err_free_req:
 217        kfree(fw_req);
 218
 219        return ERR_PTR(ret);
 220}
 221
 222static int fw_download_find_firmware(struct gb_operation *op)
 223{
 224        struct gb_connection *connection = op->connection;
 225        struct fw_download *fw_download = gb_connection_get_data(connection);
 226        struct gb_fw_download_find_firmware_request *request;
 227        struct gb_fw_download_find_firmware_response *response;
 228        struct fw_request *fw_req;
 229        const char *tag;
 230
 231        if (op->request->payload_size != sizeof(*request)) {
 232                dev_err(fw_download->parent,
 233                        "illegal size of find firmware request (%zu != %zu)\n",
 234                        op->request->payload_size, sizeof(*request));
 235                return -EINVAL;
 236        }
 237
 238        request = op->request->payload;
 239        tag = (const char *)request->firmware_tag;
 240
 241        /* firmware_tag must be null-terminated */
 242        if (strnlen(tag, GB_FIRMWARE_TAG_MAX_SIZE) ==
 243            GB_FIRMWARE_TAG_MAX_SIZE) {
 244                dev_err(fw_download->parent,
 245                        "firmware-tag is not null-terminated\n");
 246                return -EINVAL;
 247        }
 248
 249        fw_req = find_firmware(fw_download, tag);
 250        if (IS_ERR(fw_req))
 251                return PTR_ERR(fw_req);
 252
 253        if (!gb_operation_response_alloc(op, sizeof(*response), GFP_KERNEL)) {
 254                dev_err(fw_download->parent, "error allocating response\n");
 255                free_firmware(fw_download, fw_req);
 256                return -ENOMEM;
 257        }
 258
 259        response = op->response->payload;
 260        response->firmware_id = fw_req->firmware_id;
 261        response->size = cpu_to_le32(fw_req->fw->size);
 262
 263        dev_dbg(fw_download->parent,
 264                "firmware size is %zu bytes\n", fw_req->fw->size);
 265
 266        return 0;
 267}
 268
 269static int fw_download_fetch_firmware(struct gb_operation *op)
 270{
 271        struct gb_connection *connection = op->connection;
 272        struct fw_download *fw_download = gb_connection_get_data(connection);
 273        struct gb_fw_download_fetch_firmware_request *request;
 274        struct gb_fw_download_fetch_firmware_response *response;
 275        struct fw_request *fw_req;
 276        const struct firmware *fw;
 277        unsigned int offset, size;
 278        u8 firmware_id;
 279        int ret = 0;
 280
 281        if (op->request->payload_size != sizeof(*request)) {
 282                dev_err(fw_download->parent,
 283                        "Illegal size of fetch firmware request (%zu %zu)\n",
 284                        op->request->payload_size, sizeof(*request));
 285                return -EINVAL;
 286        }
 287
 288        request = op->request->payload;
 289        offset = le32_to_cpu(request->offset);
 290        size = le32_to_cpu(request->size);
 291        firmware_id = request->firmware_id;
 292
 293        fw_req = get_fw_req(fw_download, firmware_id);
 294        if (!fw_req) {
 295                dev_err(fw_download->parent,
 296                        "firmware not available for id: %02u\n", firmware_id);
 297                return -EINVAL;
 298        }
 299
 300        /* Make sure work handler isn't running in parallel */
 301        cancel_delayed_work_sync(&fw_req->dwork);
 302
 303        /* We timed-out before reaching here ? */
 304        if (fw_req->disabled) {
 305                ret = -ETIMEDOUT;
 306                goto put_fw;
 307        }
 308
 309        /*
 310         * Firmware download must finish within a limited time interval. If it
 311         * doesn't, then we might have a buggy Module on the other side. Abort
 312         * download.
 313         */
 314        ret = exceeds_release_timeout(fw_req);
 315        if (ret)
 316                goto put_fw;
 317
 318        fw = fw_req->fw;
 319
 320        if (offset >= fw->size || size > fw->size - offset) {
 321                dev_err(fw_download->parent,
 322                        "bad fetch firmware request (offs = %u, size = %u)\n",
 323                        offset, size);
 324                ret = -EINVAL;
 325                goto put_fw;
 326        }
 327
 328        if (!gb_operation_response_alloc(op, sizeof(*response) + size,
 329                                         GFP_KERNEL)) {
 330                dev_err(fw_download->parent,
 331                        "error allocating fetch firmware response\n");
 332                ret = -ENOMEM;
 333                goto put_fw;
 334        }
 335
 336        response = op->response->payload;
 337        memcpy(response->data, fw->data + offset, size);
 338
 339        dev_dbg(fw_download->parent,
 340                "responding with firmware (offs = %u, size = %u)\n", offset,
 341                size);
 342
 343        /* Refresh timeout */
 344        schedule_delayed_work(&fw_req->dwork, NEXT_REQ_TIMEOUT_J);
 345
 346put_fw:
 347        put_fw_req(fw_req);
 348
 349        return ret;
 350}
 351
 352static int fw_download_release_firmware(struct gb_operation *op)
 353{
 354        struct gb_connection *connection = op->connection;
 355        struct fw_download *fw_download = gb_connection_get_data(connection);
 356        struct gb_fw_download_release_firmware_request *request;
 357        struct fw_request *fw_req;
 358        u8 firmware_id;
 359
 360        if (op->request->payload_size != sizeof(*request)) {
 361                dev_err(fw_download->parent,
 362                        "Illegal size of release firmware request (%zu %zu)\n",
 363                        op->request->payload_size, sizeof(*request));
 364                return -EINVAL;
 365        }
 366
 367        request = op->request->payload;
 368        firmware_id = request->firmware_id;
 369
 370        fw_req = get_fw_req(fw_download, firmware_id);
 371        if (!fw_req) {
 372                dev_err(fw_download->parent,
 373                        "firmware not available for id: %02u\n", firmware_id);
 374                return -EINVAL;
 375        }
 376
 377        cancel_delayed_work_sync(&fw_req->dwork);
 378
 379        free_firmware(fw_download, fw_req);
 380        put_fw_req(fw_req);
 381
 382        dev_dbg(fw_download->parent, "release firmware\n");
 383
 384        return 0;
 385}
 386
 387int gb_fw_download_request_handler(struct gb_operation *op)
 388{
 389        u8 type = op->type;
 390
 391        switch (type) {
 392        case GB_FW_DOWNLOAD_TYPE_FIND_FIRMWARE:
 393                return fw_download_find_firmware(op);
 394        case GB_FW_DOWNLOAD_TYPE_FETCH_FIRMWARE:
 395                return fw_download_fetch_firmware(op);
 396        case GB_FW_DOWNLOAD_TYPE_RELEASE_FIRMWARE:
 397                return fw_download_release_firmware(op);
 398        default:
 399                dev_err(&op->connection->bundle->dev,
 400                        "unsupported request: %u\n", type);
 401                return -EINVAL;
 402        }
 403}
 404
 405int gb_fw_download_connection_init(struct gb_connection *connection)
 406{
 407        struct fw_download *fw_download;
 408        int ret;
 409
 410        if (!connection)
 411                return 0;
 412
 413        fw_download = kzalloc(sizeof(*fw_download), GFP_KERNEL);
 414        if (!fw_download)
 415                return -ENOMEM;
 416
 417        fw_download->parent = &connection->bundle->dev;
 418        INIT_LIST_HEAD(&fw_download->fw_requests);
 419        ida_init(&fw_download->id_map);
 420        gb_connection_set_data(connection, fw_download);
 421        fw_download->connection = connection;
 422        mutex_init(&fw_download->mutex);
 423
 424        ret = gb_connection_enable(connection);
 425        if (ret)
 426                goto err_destroy_id_map;
 427
 428        return 0;
 429
 430err_destroy_id_map:
 431        ida_destroy(&fw_download->id_map);
 432        kfree(fw_download);
 433
 434        return ret;
 435}
 436
 437void gb_fw_download_connection_exit(struct gb_connection *connection)
 438{
 439        struct fw_download *fw_download;
 440        struct fw_request *fw_req, *tmp;
 441
 442        if (!connection)
 443                return;
 444
 445        fw_download = gb_connection_get_data(connection);
 446        gb_connection_disable(fw_download->connection);
 447
 448        /*
 449         * Make sure we have a reference to the pending requests, before they
 450         * are freed from the timeout handler.
 451         */
 452        mutex_lock(&fw_download->mutex);
 453        list_for_each_entry(fw_req, &fw_download->fw_requests, node)
 454                kref_get(&fw_req->kref);
 455        mutex_unlock(&fw_download->mutex);
 456
 457        /* Release pending firmware packages */
 458        list_for_each_entry_safe(fw_req, tmp, &fw_download->fw_requests, node) {
 459                cancel_delayed_work_sync(&fw_req->dwork);
 460                free_firmware(fw_download, fw_req);
 461                put_fw_req(fw_req);
 462        }
 463
 464        ida_destroy(&fw_download->id_map);
 465        kfree(fw_download);
 466}
 467