linux/drivers/staging/csr/csr_wifi_hip_download.c
<<
>>
Prefs
   1/*****************************************************************************
   2
   3            (c) Cambridge Silicon Radio Limited 2012
   4            All rights reserved and confidential information of CSR
   5
   6            Refer to LICENSE.txt included with this source for details
   7            on the license terms.
   8
   9*****************************************************************************/
  10
  11/*
  12 * ---------------------------------------------------------------------------
  13 * FILE: csr_wifi_hip_download.c
  14 *
  15 * PURPOSE:
  16 *      Routines for downloading firmware to UniFi.
  17 *
  18 * ---------------------------------------------------------------------------
  19 */
  20#include <linux/slab.h>
  21#include "csr_wifi_hip_unifi.h"
  22#include "csr_wifi_hip_unifiversion.h"
  23#include "csr_wifi_hip_card.h"
  24#include "csr_wifi_hip_xbv.h"
  25
  26#undef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH
  27
  28static CsrResult do_patch_download(card_t *card, void *dlpriv,
  29                                   xbv1_t *pfwinfo, u32 boot_ctrl_addr);
  30
  31static CsrResult do_patch_convert_download(card_t *card,
  32                                           void *dlpriv, xbv1_t *pfwinfo);
  33
  34/*
  35 * ---------------------------------------------------------------------------
  36 *  _find_in_slut
  37 *
  38 *      Find the offset of the appropriate object in the SLUT of a card
  39 *
  40 *  Arguments:
  41 *      card            Pointer to card struct
  42 *      psym            Pointer to symbol object.
  43 *                         id set up by caller
  44 *                         obj will be set up by this function
  45 *      pslut           Pointer to SLUT address, if 0xffffffff then it must be
  46 *                         read from the chip.
  47 *  Returns:
  48 *      CSR_RESULT_SUCCESS on success
  49 *      Non-zero on error,
  50 *      CSR_WIFI_HIP_RESULT_NOT_FOUND if not found
  51 * ---------------------------------------------------------------------------
  52 */
  53static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut)
  54{
  55    u32 slut_address;
  56    u16 finger_print;
  57    CsrResult r;
  58    CsrResult csrResult;
  59
  60    /* Get SLUT address */
  61    if (*pslut == 0xffffffff)
  62    {
  63        r = card_wait_for_firmware_to_start(card, &slut_address);
  64        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
  65        {
  66            return r;
  67        }
  68        if (r != CSR_RESULT_SUCCESS)
  69        {
  70            unifi_error(card->ospriv, "Firmware hasn't started\n");
  71            return r;
  72        }
  73        *pslut = slut_address;
  74
  75        /*
  76         * Firmware has started so set the SDIO bus clock to the initial speed,
  77         * faster than UNIFI_SDIO_CLOCK_SAFE_HZ, to speed up the f/w download.
  78         */
  79        csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ);
  80        if (csrResult != CSR_RESULT_SUCCESS)
  81        {
  82            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
  83            return r;
  84        }
  85        card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;
  86    }
  87    else
  88    {
  89        slut_address = *pslut;  /* Use previously discovered address */
  90    }
  91    unifi_trace(card->ospriv, UDBG4, "SLUT addr: 0x%lX\n", slut_address);
  92
  93    /*
  94     * Check the SLUT fingerprint.
  95     * The slut_address is a generic pointer so we must use unifi_card_read16().
  96     */
  97    unifi_trace(card->ospriv, UDBG4, "Looking for SLUT finger print\n");
  98    finger_print = 0;
  99    r = unifi_card_read16(card, slut_address, &finger_print);
 100    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
 101    {
 102        return r;
 103    }
 104    if (r != CSR_RESULT_SUCCESS)
 105    {
 106        unifi_error(card->ospriv, "Failed to read SLUT finger print\n");
 107        return r;
 108    }
 109
 110    if (finger_print != SLUT_FINGERPRINT)
 111    {
 112        unifi_error(card->ospriv, "Failed to find SLUT fingerprint\n");
 113        return CSR_RESULT_FAILURE;
 114    }
 115
 116    /* Symbol table starts imedately after the fingerprint */
 117    slut_address += 2;
 118
 119    while (1)
 120    {
 121        u16 id;
 122        u32 obj;
 123
 124        r = unifi_card_read16(card, slut_address, &id);
 125        if (r != CSR_RESULT_SUCCESS)
 126        {
 127            return r;
 128        }
 129        slut_address += 2;
 130
 131        if (id == CSR_SLT_END)
 132        {
 133            /* End of table reached: not found */
 134            r = CSR_WIFI_HIP_RESULT_RANGE;
 135            break;
 136        }
 137
 138        r = unifi_read32(card, slut_address, &obj);
 139        if (r != CSR_RESULT_SUCCESS)
 140        {
 141            return r;
 142        }
 143        slut_address += 4;
 144
 145        unifi_trace(card->ospriv, UDBG3, "  found SLUT id %02d.%08lx\n", id, obj);
 146
 147        r = CSR_WIFI_HIP_RESULT_NOT_FOUND;
 148        /* Found search term? */
 149        if (id == psym->id)
 150        {
 151            unifi_trace(card->ospriv, UDBG1, " matched SLUT id %02d.%08lx\n", id, obj);
 152            psym->obj = obj;
 153            r = CSR_RESULT_SUCCESS;
 154            break;
 155        }
 156    }
 157
 158    return r;
 159}
 160
 161
 162/*
 163 * ---------------------------------------------------------------------------
 164 *  do_patch_convert_download
 165 *
 166 *      Download the given firmware image to the UniFi, converting from FWDL
 167 *      to PTDL XBV format.
 168 *
 169 *  Arguments:
 170 *      card            Pointer to card struct
 171 *      dlpriv          Pointer to source firmware image
 172 *      fwinfo          Pointer to source firmware info struct
 173 *
 174 *  Returns:
 175 *      CSR_RESULT_SUCCESS on success, CSR error code on error
 176 *
 177 *  Notes:
 178 * ---------------------------------------------------------------------------
 179 */
 180static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *pfwinfo)
 181{
 182    CsrResult r;
 183    u32 slut_base = 0xffffffff;
 184    void *pfw;
 185    u32 psize;
 186    symbol_t sym;
 187
 188    /* Reset the chip to guarantee that the ROM loader is running */
 189    r = unifi_init(card);
 190    if (r != CSR_RESULT_SUCCESS)
 191    {
 192        unifi_error(card->ospriv,
 193                    "do_patch_convert_download: failed to re-init UniFi\n");
 194        return r;
 195    }
 196
 197    /* If no unifi_helper is running, the firmware version must be read */
 198    if (card->build_id == 0)
 199    {
 200        u32 ver = 0;
 201        sym.id = CSR_SLT_BUILD_ID_NUMBER;
 202        sym.obj = 0; /* To be updated by _find_in_slut() */
 203
 204        unifi_trace(card->ospriv, UDBG1, "Need f/w version\n");
 205
 206        /* Find chip build id entry in SLUT */
 207        r = _find_in_slut(card, &sym, &slut_base);
 208        if (r != CSR_RESULT_SUCCESS)
 209        {
 210            unifi_error(card->ospriv, "Failed to find CSR_SLT_BUILD_ID_NUMBER\n");
 211            return CSR_RESULT_FAILURE;
 212        }
 213
 214        /* Read running f/w version */
 215        r = unifi_read32(card, sym.obj, &ver);
 216        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
 217        {
 218            return r;
 219        }
 220        if (r != CSR_RESULT_SUCCESS)
 221        {
 222            unifi_error(card->ospriv, "Failed to read f/w id\n");
 223            return CSR_RESULT_FAILURE;
 224        }
 225        card->build_id = ver;
 226    }
 227
 228    /* Convert the ptest firmware to a patch against the running firmware */
 229    pfw = xbv_to_patch(card, unifi_fw_read, dlpriv, pfwinfo, &psize);
 230    if (!pfw)
 231    {
 232        unifi_error(card->ospriv, "Failed to convert f/w to patch");
 233        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
 234    }
 235    else
 236    {
 237        void *desc;
 238        sym.id = CSR_SLT_BOOT_LOADER_CONTROL;
 239        sym.obj = 0; /* To be updated by _find_in_slut() */
 240
 241        /* Find boot loader control entry in SLUT */
 242        r = _find_in_slut(card, &sym, &slut_base);
 243        if (r != CSR_RESULT_SUCCESS)
 244        {
 245            unifi_error(card->ospriv, "Failed to find BOOT_LOADER_CONTROL\n");
 246            kfree(pfw);
 247            return CSR_RESULT_FAILURE;
 248        }
 249
 250        r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
 251        if (r != CSR_RESULT_SUCCESS)
 252        {
 253            unifi_error(card->ospriv, "Failed to wake UniFi\n");
 254        }
 255
 256        /* Get a dlpriv for the patch buffer so that unifi_fw_read() can
 257         * access it.
 258         */
 259        desc = unifi_fw_open_buffer(card->ospriv, pfw, psize);
 260        if (!desc)
 261        {
 262            kfree(pfw);
 263            return CSR_WIFI_HIP_RESULT_NO_MEMORY;
 264        }
 265
 266        /* Download the patch */
 267        unifi_info(card->ospriv, "Downloading converted f/w as patch\n");
 268        r = unifi_dl_patch(card, desc, sym.obj);
 269        kfree(pfw);
 270        unifi_fw_close_buffer(card->ospriv, desc);
 271
 272        if (r != CSR_RESULT_SUCCESS)
 273        {
 274            unifi_error(card->ospriv, "Converted patch download failed\n");
 275            return r;
 276        }
 277        else
 278        {
 279            unifi_trace(card->ospriv, UDBG1, "Converted patch downloaded\n");
 280        }
 281
 282        /* This command starts the firmware */
 283        r = unifi_do_loader_op(card, sym.obj + 6, UNIFI_BOOT_LOADER_RESTART);
 284        if (r != CSR_RESULT_SUCCESS)
 285        {
 286            unifi_error(card->ospriv, "Failed to write loader restart cmd\n");
 287        }
 288
 289        return r;
 290    }
 291}
 292
 293
 294/*
 295 * ---------------------------------------------------------------------------
 296 *  unifi_dl_firmware
 297 *
 298 *      Download the given firmware image to the UniFi.
 299 *
 300 *  Arguments:
 301 *      card            Pointer to card struct
 302 *      dlpriv          A context pointer from the calling function to be
 303 *                      passed when calling unifi_fw_read().
 304 *
 305 *  Returns:
 306 *      CSR_RESULT_SUCCESS on success,
 307 *      CSR_WIFI_HIP_RESULT_NO_MEMORY         memory allocation failed
 308 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         error in XBV file
 309 *      CSR_RESULT_FAILURE            SDIO error
 310 *
 311 *  Notes:
 312 *      Stops and resets the chip, does the download and runs the new
 313 *      firmware.
 314 * ---------------------------------------------------------------------------
 315 */
 316CsrResult unifi_dl_firmware(card_t *card, void *dlpriv)
 317{
 318    xbv1_t *fwinfo;
 319    CsrResult r;
 320
 321    fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL);
 322    if (fwinfo == NULL)
 323    {
 324        unifi_error(card->ospriv, "Failed to allocate memory for firmware\n");
 325        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
 326    }
 327
 328    /*
 329     * Scan the firmware file to find the TLVs we are interested in.
 330     * These are:
 331     *   - check we support the file format version in VERF
 332     *   - SLTP Symbol Lookup Table Pointer
 333     *   - FWDL firmware download segments
 334     *   - FWOV firmware overlay segment
 335     *   - VMEQ Register probe tests to verify matching h/w
 336     */
 337    r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo);
 338    if (r != CSR_RESULT_SUCCESS || fwinfo->mode != xbv_firmware)
 339    {
 340        unifi_error(card->ospriv, "File type is %s, expected firmware.\n",
 341                    fwinfo->mode == xbv_patch?"patch" : "unknown");
 342        kfree(fwinfo);
 343        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 344    }
 345
 346    /* UF6xxx doesn't accept firmware, only patches. Therefore we convert
 347     * the file to patch format with version numbers matching the current
 348     * running firmware, and then download via the patch mechanism.
 349     * The sole purpose of this is to support production test firmware across
 350     * different ROM releases, the test firmware being provided in non-patch
 351     * format.
 352     */
 353    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
 354    {
 355        unifi_info(card->ospriv, "Must convert f/w to patch format\n");
 356        r = do_patch_convert_download(card, dlpriv, fwinfo);
 357    }
 358    else
 359    {
 360        /* Older UniFi chips allowed firmware to be directly loaded onto the
 361         * chip, which is no longer supported.
 362         */
 363        unifi_error(card->ospriv, "Only patch downloading supported\n");
 364        r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 365    }
 366
 367    kfree(fwinfo);
 368    return r;
 369} /* unifi_dl_firmware() */
 370
 371
 372/*
 373 * ---------------------------------------------------------------------------
 374 *  unifi_dl_patch
 375 *
 376 *      Load the given patch set into UniFi.
 377 *
 378 *  Arguments:
 379 *      card            Pointer to card struct
 380 *      dlpriv          The os specific handle to the firmware file.
 381 *      boot_ctrl       The address of the boot loader control structure.
 382 *
 383 *  Returns:
 384 *      CSR_RESULT_SUCCESS on success,
 385 *      CSR_WIFI_HIP_RESULT_NO_MEMORY         memory allocation failed
 386 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         error in XBV file
 387 *      CSR_RESULT_FAILURE            SDIO error
 388 *
 389 *  Notes:
 390 *      This ends up telling UniFi to restart.
 391 * ---------------------------------------------------------------------------
 392 */
 393CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl)
 394{
 395    xbv1_t *fwinfo;
 396    CsrResult r;
 397
 398    unifi_info(card->ospriv, "unifi_dl_patch %p %08x\n", dlpriv, boot_ctrl);
 399
 400    fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL);
 401    if (fwinfo == NULL)
 402    {
 403        unifi_error(card->ospriv, "Failed to allocate memory for patches\n");
 404        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
 405    }
 406
 407    /*
 408     * Scan the firmware file to find the TLVs we are interested in.
 409     * These are:
 410     *   - check we support the file format version in VERF
 411     *   - FWID The build ID of the ROM that we can patch
 412     *   - PTDL patch download segments
 413     */
 414    r = xbv1_parse(card, unifi_fw_read, dlpriv, fwinfo);
 415    if (r != CSR_RESULT_SUCCESS || fwinfo->mode != xbv_patch)
 416    {
 417        kfree(fwinfo);
 418        unifi_error(card->ospriv, "Failed to read in patch file\n");
 419        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 420    }
 421
 422    /*
 423     * We have to check the build id read from the SLUT against that
 424     * for the patch file.  They have to match exactly.
 425     *    "card->build_id" == XBV1.PTCH.FWID
 426     */
 427    if (card->build_id != fwinfo->build_id)
 428    {
 429        unifi_error(card->ospriv, "Wrong patch file for chip (chip = %lu, file = %lu)\n",
 430                    card->build_id, fwinfo->build_id);
 431        kfree(fwinfo);
 432#ifndef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH
 433        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 434#else
 435        fwinfo = NULL;
 436        dlpriv = NULL;
 437        return CSR_RESULT_SUCCESS;
 438#endif
 439    }
 440
 441    r = do_patch_download(card, dlpriv, fwinfo, boot_ctrl);
 442    if (r != CSR_RESULT_SUCCESS)
 443    {
 444        unifi_error(card->ospriv, "Failed to patch image\n");
 445    }
 446
 447    kfree(fwinfo);
 448
 449    return r;
 450} /* unifi_dl_patch() */
 451
 452
 453void* unifi_dl_fw_read_start(card_t *card, s8 is_fw)
 454{
 455    card_info_t card_info;
 456
 457    unifi_card_info(card, &card_info);
 458    unifi_trace(card->ospriv, UDBG5,
 459                "id=%d, ver=0x%x, fw_build=%u, fw_hip=0x%x, block_size=%d\n",
 460                card_info.chip_id, card_info.chip_version,
 461                card_info.fw_build, card_info.fw_hip_version,
 462                card_info.sdio_block_size);
 463
 464    return unifi_fw_read_start(card->ospriv, is_fw, &card_info);
 465}
 466
 467
 468/*
 469 * ---------------------------------------------------------------------------
 470 *  safe_read_shared_location
 471 *
 472 *      Read a shared memory location repeatedly until we get two readings
 473 *      the same.
 474 *
 475 *  Arguments:
 476 *      card            Pointer to card context struct.
 477 *      unifi_addr      UniFi shared-data-memory address to access.
 478 *      pdata           Pointer to a byte variable for the value read.
 479 *
 480 *
 481 *  Returns:
 482 *      CSR_RESULT_SUCCESS on success, CSR error code on failure
 483 * ---------------------------------------------------------------------------
 484 */
 485static CsrResult safe_read_shared_location(card_t *card, u32 address, u8 *pdata)
 486{
 487    CsrResult r;
 488    u16 limit = 1000;
 489    u8 b, b2;
 490
 491    *pdata = 0;
 492
 493    r = unifi_read_8_or_16(card, address, &b);
 494    if (r != CSR_RESULT_SUCCESS)
 495    {
 496        return r;
 497    }
 498
 499    while (limit--)
 500    {
 501        r = unifi_read_8_or_16(card, address, &b2);
 502        if (r != CSR_RESULT_SUCCESS)
 503        {
 504            return r;
 505        }
 506
 507        /* When we have a stable value, return it */
 508        if (b == b2)
 509        {
 510            *pdata = b;
 511            return CSR_RESULT_SUCCESS;
 512        }
 513
 514        b = b2;
 515    }
 516
 517    return CSR_RESULT_FAILURE;
 518} /* safe_read_shared_location() */
 519
 520
 521/*
 522 * ---------------------------------------------------------------------------
 523 *  unifi_do_loader_op
 524 *
 525 *      Send a loader / boot_loader command to the UniFi and wait for
 526 *      it to complete.
 527 *
 528 *  Arguments:
 529 *      card            Pointer to card context struct.
 530 *      op_addr         The address of the loader operation control word.
 531 *      opcode          The operation to perform.
 532 *
 533 *  Returns:
 534 *      CSR_RESULT_SUCCESS    on success
 535 *      CSR_RESULT_FAILURE    SDIO error or SDIO/XAP timeout
 536 * ---------------------------------------------------------------------------
 537 */
 538
 539/*
 540 * Ideally instead of sleeping, we want to busy wait.
 541 * Currently there is no framework API to do this. When it becomes available,
 542 * we can use it to busy wait using usecs
 543 */
 544#define OPERATION_TIMEOUT_LOOPS (100)  /* when OPERATION_TIMEOUT_DELAY==1, (500) otherwise */
 545#define OPERATION_TIMEOUT_DELAY 1      /* msec, or 200usecs */
 546
 547CsrResult unifi_do_loader_op(card_t *card, u32 op_addr, u8 opcode)
 548{
 549    CsrResult r;
 550    s16 op_retries;
 551
 552    unifi_trace(card->ospriv, UDBG4, "Loader cmd 0x%0x -> 0x%08x\n", opcode, op_addr);
 553
 554    /* Set the Operation command byte to the opcode */
 555    r = unifi_write_8_or_16(card, op_addr, opcode);
 556    if (r != CSR_RESULT_SUCCESS)
 557    {
 558        unifi_error(card->ospriv, "Failed to write loader copy command\n");
 559        return r;
 560    }
 561
 562    /* Wait for Operation command byte to be Idle */
 563    /* Typically takes ~100us */
 564    op_retries = 0;
 565    r = CSR_RESULT_SUCCESS;
 566    while (1)
 567    {
 568        u8 op;
 569
 570        /*
 571         * Read the memory location until two successive reads give
 572         * the same value.
 573         * Then handle it.
 574         */
 575        r = safe_read_shared_location(card, op_addr, &op);
 576        if (r != CSR_RESULT_SUCCESS)
 577        {
 578            unifi_error(card->ospriv, "Failed to read loader status\n");
 579            break;
 580        }
 581
 582        if (op == UNIFI_LOADER_IDLE)
 583        {
 584            /* Success */
 585            break;
 586        }
 587
 588        if (op != opcode)
 589        {
 590            unifi_error(card->ospriv, "Error reported by loader: 0x%X\n", op);
 591            r = CSR_RESULT_FAILURE;
 592            break;
 593        }
 594
 595        /* Allow 500us timeout */
 596        if (++op_retries >= OPERATION_TIMEOUT_LOOPS)
 597        {
 598            unifi_error(card->ospriv, "Timeout waiting for loader to ack transfer\n");
 599            /* Stop XAPs to aid post-mortem */
 600            r = unifi_card_stop_processor(card, UNIFI_PROC_BOTH);
 601            if (r != CSR_RESULT_SUCCESS)
 602            {
 603                unifi_error(card->ospriv, "Failed to stop UniFi processors\n");
 604            }
 605            else
 606            {
 607                r = CSR_RESULT_FAILURE;
 608            }
 609            break;
 610        }
 611        CsrThreadSleep(OPERATION_TIMEOUT_DELAY);
 612    } /* Loop exits with r != CSR_RESULT_SUCCESS on error */
 613
 614    return r;
 615}     /* unifi_do_loader_op() */
 616
 617
 618/*
 619 * ---------------------------------------------------------------------------
 620 *  send_ptdl_to_unifi
 621 *
 622 *      Copy a patch block from userland to the UniFi.
 623 *      This function reads data, 2K at a time, from userland and writes
 624 *      it to the UniFi.
 625 *
 626 *  Arguments:
 627 *      card            A pointer to the card structure
 628 *      dlpriv          The os specific handle for the firmware file
 629 *      ptdl            A pointer ot the PTDL block
 630 *      handle          The buffer handle to use for the xfer
 631 *      op_addr         The address of the loader operation control word
 632 *
 633 *  Returns:
 634 *      Number of bytes sent (Positive) or negative value indicating
 635 *      error code:
 636 *      CSR_WIFI_HIP_RESULT_NO_MEMORY         memory allocation failed
 637 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE         error in XBV file
 638 *      CSR_RESULT_FAILURE            SDIO error
 639 * ---------------------------------------------------------------------------
 640 */
 641static CsrResult send_ptdl_to_unifi(card_t *card, void *dlpriv,
 642                                    const struct PTDL *ptdl, u32 handle,
 643                                    u32 op_addr)
 644{
 645    u32 offset;
 646    u8 *buf;
 647    s32 data_len;
 648    u32 write_len;
 649    CsrResult r;
 650    const u16 buf_size = 2 * 1024;
 651
 652    offset = ptdl->dl_offset;
 653    data_len = ptdl->dl_size;
 654
 655    if (data_len > buf_size)
 656    {
 657        unifi_error(card->ospriv, "PTDL block is too large (%u)\n",
 658                    ptdl->dl_size);
 659        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 660    }
 661
 662    buf = kmalloc(buf_size, GFP_KERNEL);
 663    if (buf == NULL)
 664    {
 665        unifi_error(card->ospriv, "Failed to allocate transfer buffer for firmware download\n");
 666        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
 667    }
 668
 669    r = CSR_RESULT_SUCCESS;
 670
 671    if (unifi_fw_read(card->ospriv, dlpriv, offset, buf, data_len) != data_len)
 672    {
 673        unifi_error(card->ospriv, "Failed to read from file\n");
 674    }
 675    else
 676    {
 677        /* We can always round these if the host wants to */
 678        if (card->sdio_io_block_pad)
 679        {
 680            write_len = (data_len + (card->sdio_io_block_size - 1)) &
 681                        ~(card->sdio_io_block_size - 1);
 682
 683            /* Zero out the rest of the buffer (This isn't needed, but it
 684             * makes debugging things later much easier). */
 685            memset(buf + data_len, 0, write_len - data_len);
 686        }
 687        else
 688        {
 689            write_len = data_len;
 690        }
 691
 692        r = unifi_bulk_rw_noretry(card, handle, buf, write_len, UNIFI_SDIO_WRITE);
 693        if (r != CSR_RESULT_SUCCESS)
 694        {
 695            unifi_error(card->ospriv, "CMD53 failed writing %d bytes to handle %ld\n",
 696                        data_len, handle);
 697        }
 698        else
 699        {
 700            /*
 701             * Can change the order of things to overlap read from file
 702             * with copy to unifi
 703             */
 704            r = unifi_do_loader_op(card, op_addr, UNIFI_BOOT_LOADER_PATCH);
 705        }
 706    }
 707
 708    kfree(buf);
 709
 710    if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE)
 711    {
 712        unifi_error(card->ospriv, "Failed to copy block of %u bytes to UniFi\n",
 713                    ptdl->dl_size);
 714    }
 715
 716    return r;
 717} /* send_ptdl_to_unifi() */
 718
 719
 720/*
 721 * ---------------------------------------------------------------------------
 722 *  do_patch_download
 723 *
 724 *      This function downloads a set of patches to UniFi and then
 725 *      causes it to restart.
 726 *
 727 *  Arguments:
 728 *      card            Pointer to card struct.
 729 *      dlpriv          A context pointer from the calling function to be
 730 *                      used when reading the XBV file.  This can be NULL
 731 *                      in which case not patches are applied.
 732 *      pfwinfo         Pointer to a fwinfo struct describing the f/w
 733 *                      XBV file.
 734 *      boot_ctrl_addr  The address of the boot loader control structure.
 735 *
 736 *  Returns:
 737 *      0 on success, or an error code
 738 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE for a bad laoader version number
 739 * ---------------------------------------------------------------------------
 740 */
 741static CsrResult do_patch_download(card_t *card, void *dlpriv, xbv1_t *pfwinfo, u32 boot_ctrl_addr)
 742{
 743    CsrResult r;
 744    s32 i;
 745    u16 loader_version;
 746    u16 handle;
 747    u32 total_bytes;
 748
 749    /*
 750     * Read info from the SDIO Loader Control Data Structure
 751     */
 752    /* Check the loader version */
 753    r = unifi_card_read16(card, boot_ctrl_addr, &loader_version);
 754    if (r != CSR_RESULT_SUCCESS)
 755    {
 756        unifi_error(card->ospriv, "Patch download: Failed to read loader version\n");
 757        return r;
 758    }
 759    unifi_trace(card->ospriv, UDBG2, "Patch download: boot loader version 0x%04X\n", loader_version);
 760    switch (loader_version)
 761    {
 762        case 0x0000:
 763            break;
 764
 765        default:
 766            unifi_error(card->ospriv, "Patch loader version (0x%04X) is not supported by this driver\n",
 767                        loader_version);
 768            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
 769    }
 770
 771    /* Retrieve the handle to use with CMD53 */
 772    r = unifi_card_read16(card, boot_ctrl_addr + 4, &handle);
 773    if (r != CSR_RESULT_SUCCESS)
 774    {
 775        unifi_error(card->ospriv, "Patch download: Failed to read loader handle\n");
 776        return r;
 777    }
 778
 779    /* Set the mask of LEDs to flash */
 780    if (card->loader_led_mask)
 781    {
 782        r = unifi_card_write16(card, boot_ctrl_addr + 2,
 783                               (u16)card->loader_led_mask);
 784        if (r != CSR_RESULT_SUCCESS)
 785        {
 786            unifi_error(card->ospriv, "Patch download: Failed to write LED mask\n");
 787            return r;
 788        }
 789    }
 790
 791    total_bytes = 0;
 792
 793    /* Copy download data to UniFi memory */
 794    for (i = 0; i < pfwinfo->num_ptdl; i++)
 795    {
 796        unifi_trace(card->ospriv, UDBG3, "Patch download: %d Downloading for %d from offset %d\n",
 797                    i,
 798                    pfwinfo->ptdl[i].dl_size,
 799                    pfwinfo->ptdl[i].dl_offset);
 800
 801        r = send_ptdl_to_unifi(card, dlpriv, &pfwinfo->ptdl[i],
 802                               handle, boot_ctrl_addr + 6);
 803        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
 804        {
 805            return r;
 806        }
 807        if (r != CSR_RESULT_SUCCESS)
 808        {
 809            unifi_error(card->ospriv, "Patch failed after %u bytes\n",
 810                        total_bytes);
 811            return r;
 812        }
 813        total_bytes += pfwinfo->ptdl[i].dl_size;
 814    }
 815
 816    return CSR_RESULT_SUCCESS;
 817} /* do_patch_download() */
 818
 819
 820