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