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