root/drivers/staging/greybus/fw-download.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fw_req_release
  2. put_fw_req
  3. get_fw_req
  4. free_firmware
  5. fw_request_timedout
  6. exceeds_release_timeout
  7. find_firmware
  8. fw_download_find_firmware
  9. fw_download_fetch_firmware
  10. fw_download_release_firmware
  11. gb_fw_download_request_handler
  12. gb_fw_download_connection_init
  13. gb_fw_download_connection_exit

   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 <linux/greybus.h>
  14 #include "firmware.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 
  21 struct 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 
  36 struct 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 
  44 static 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  */
  86 static 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 */
  92 static 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 
 108 unlock:
 109         mutex_unlock(&fw_download->mutex);
 110 
 111         return fw_req;
 112 }
 113 
 114 static 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 
 129 static 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 
 144 static 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 */
 162 static 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 
 214 err_free_id:
 215         ida_simple_remove(&fw_download->id_map, fw_req->firmware_id);
 216 err_free_req:
 217         kfree(fw_req);
 218 
 219         return ERR_PTR(ret);
 220 }
 221 
 222 static 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 
 269 static 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 
 346 put_fw:
 347         put_fw_req(fw_req);
 348 
 349         return ret;
 350 }
 351 
 352 static 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 
 387 int 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 
 405 int 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 
 430 err_destroy_id_map:
 431         ida_destroy(&fw_download->id_map);
 432         kfree(fw_download);
 433 
 434         return ret;
 435 }
 436 
 437 void 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 }

/* [<][>][^][v][top][bottom][index][help] */