Merge remote-tracking branches 'asoc/fix/adsp', 'asoc/fix/arizona', 'asoc/fix/atmel...
[linux-drm-fsl-dcu.git] / drivers / staging / ft1000 / ft1000-usb / ft1000_download.c
1 /*
2 * CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
3 *
4 * This file is part of Express Card USB Driver
5 */
6
7 #include <linux/init.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/netdevice.h>
11 #include <linux/etherdevice.h>
12 #include <linux/usb.h>
13 #include <linux/vmalloc.h>
14 #include "ft1000_usb.h"
15
16
17 #define  DWNLD_HANDSHAKE_LOC     0x02
18 #define  DWNLD_TYPE_LOC          0x04
19 #define  DWNLD_SIZE_MSW_LOC      0x06
20 #define  DWNLD_SIZE_LSW_LOC      0x08
21 #define  DWNLD_PS_HDR_LOC        0x0A
22
23 #define  MAX_DSP_WAIT_LOOPS      40
24 #define  DSP_WAIT_SLEEP_TIME     1000       /* 1 millisecond */
25 #define  DSP_WAIT_DISPATCH_LVL   50         /* 50 usec */
26
27 #define  HANDSHAKE_TIMEOUT_VALUE 0xF1F1
28 #define  HANDSHAKE_RESET_VALUE   0xFEFE   /* When DSP requests startover */
29 #define  HANDSHAKE_RESET_VALUE_USB   0xFE7E   /* When DSP requests startover */
30 #define  HANDSHAKE_DSP_BL_READY  0xFEFE   /* At start DSP writes this when bootloader ready */
31 #define  HANDSHAKE_DSP_BL_READY_USB  0xFE7E   /* At start DSP writes this when bootloader ready */
32 #define  HANDSHAKE_DRIVER_READY  0xFFFF   /* Driver writes after receiving 0xFEFE */
33 #define  HANDSHAKE_SEND_DATA     0x0000   /* DSP writes this when ready for more data */
34
35 #define  HANDSHAKE_REQUEST       0x0001   /* Request from DSP */
36 #define  HANDSHAKE_RESPONSE      0x0000   /* Satisfied DSP request */
37
38 #define  REQUEST_CODE_LENGTH     0x0000
39 #define  REQUEST_RUN_ADDRESS     0x0001
40 #define  REQUEST_CODE_SEGMENT    0x0002   /* In WORD count */
41 #define  REQUEST_DONE_BL         0x0003
42 #define  REQUEST_DONE_CL         0x0004
43 #define  REQUEST_VERSION_INFO    0x0005
44 #define  REQUEST_CODE_BY_VERSION 0x0006
45 #define  REQUEST_MAILBOX_DATA    0x0007
46 #define  REQUEST_FILE_CHECKSUM   0x0008
47
48 #define  STATE_START_DWNLD       0x01
49 #define  STATE_BOOT_DWNLD        0x02
50 #define  STATE_CODE_DWNLD        0x03
51 #define  STATE_DONE_DWNLD        0x04
52 #define  STATE_SECTION_PROV      0x05
53 #define  STATE_DONE_PROV         0x06
54 #define  STATE_DONE_FILE         0x07
55
56 #define  MAX_LENGTH              0x7f0
57
58 // Temporary download mechanism for Magnemite
59 #define  DWNLD_MAG_TYPE_LOC          0x00
60 #define  DWNLD_MAG_LEN_LOC           0x01
61 #define  DWNLD_MAG_ADDR_LOC          0x02
62 #define  DWNLD_MAG_CHKSUM_LOC        0x03
63 #define  DWNLD_MAG_VAL_LOC           0x04
64
65 #define  HANDSHAKE_MAG_DSP_BL_READY  0xFEFE0000   /* At start DSP writes this when bootloader ready */
66 #define  HANDSHAKE_MAG_DSP_ENTRY     0x01000000   /* Dsp writes this to request for entry address */
67 #define  HANDSHAKE_MAG_DSP_DATA      0x02000000   /* Dsp writes this to request for data block */
68 #define  HANDSHAKE_MAG_DSP_DONE      0x03000000   /* Dsp writes this to indicate download done */
69
70 #define  HANDSHAKE_MAG_DRV_READY     0xFFFF0000   /* Driver writes this to indicate ready to download */
71 #define  HANDSHAKE_MAG_DRV_DATA      0x02FECDAB   /* Driver writes this to indicate data available to DSP */
72 #define  HANDSHAKE_MAG_DRV_ENTRY     0x01FECDAB   /* Driver writes this to indicate entry point to DSP */
73
74 #define  HANDSHAKE_MAG_TIMEOUT_VALUE 0xF1F1
75
76
77 // New Magnemite downloader
78 #define  DWNLD_MAG1_HANDSHAKE_LOC     0x00
79 #define  DWNLD_MAG1_TYPE_LOC          0x01
80 #define  DWNLD_MAG1_SIZE_LOC          0x02
81 #define  DWNLD_MAG1_PS_HDR_LOC        0x03
82
83 struct dsp_file_hdr {
84    long              version_id;          // Version ID of this image format.
85    long              package_id;          // Package ID of code release.
86    long              build_date;          // Date/time stamp when file was built.
87    long              commands_offset;     // Offset to attached commands in Pseudo Hdr format.
88    long              loader_offset;       // Offset to bootloader code.
89    long              loader_code_address; // Start address of bootloader.
90    long              loader_code_end;     // Where bootloader code ends.
91    long              loader_code_size;
92    long              version_data_offset; // Offset were scrambled version data begins.
93    long              version_data_size;   // Size, in words, of scrambled version data.
94    long              nDspImages;          // Number of DSP images in file.
95 };
96
97 #pragma pack(1)
98 struct dsp_image_info {
99    long              coff_date;           // Date/time when DSP Coff image was built.
100    long              begin_offset;        // Offset in file where image begins.
101    long              end_offset;          // Offset in file where image begins.
102    long              run_address;         // On chip Start address of DSP code.
103    long              image_size;          // Size of image.
104    long              version;             // Embedded version # of DSP code.
105    unsigned short    checksum;            // DSP File checksum
106    unsigned short    pad1;
107 };
108
109
110 /* checks if the doorbell register is cleared */
111 static int check_usb_db(struct ft1000_usb *ft1000dev)
112 {
113         int loopcnt;
114         u16 temp;
115         int status;
116
117         loopcnt = 0;
118
119         while (loopcnt < 10) {
120                 status = ft1000_read_register(ft1000dev, &temp,
121                                                FT1000_REG_DOORBELL);
122                 DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n",
123                        temp);
124                 if (temp & 0x0080) {
125                         DEBUG("FT1000:Got checkusb doorbell\n");
126                         status = ft1000_write_register(ft1000dev, 0x0080,
127                                                 FT1000_REG_DOORBELL);
128                         status = ft1000_write_register(ft1000dev, 0x0100,
129                                                 FT1000_REG_DOORBELL);
130                         status = ft1000_write_register(ft1000dev,  0x8000,
131                                                 FT1000_REG_DOORBELL);
132                         break;
133                 } else {
134                         loopcnt++;
135                         msleep(10);
136                 }
137
138         }
139
140         loopcnt = 0;
141         while (loopcnt < 20) {
142                 status = ft1000_read_register(ft1000dev, &temp,
143                                                FT1000_REG_DOORBELL);
144                 DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp);
145                 if (temp & 0x8000) {
146                         loopcnt++;
147                         msleep(10);
148                 } else  {
149                         DEBUG("check_usb_db: door bell is cleared, return 0\n");
150                         return 0;
151                 }
152         }
153
154         return HANDSHAKE_MAG_TIMEOUT_VALUE;
155 }
156
157 /* gets the handshake and compares it with the expected value */
158 static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value)
159 {
160         u16 handshake;
161         int loopcnt;
162         int status = 0;
163
164         loopcnt = 0;
165
166         while (loopcnt < 100) {
167                 /* Need to clear downloader doorbell if Hartley ASIC */
168                 status = ft1000_write_register(ft1000dev,  FT1000_DB_DNLD_RX,
169                                                 FT1000_REG_DOORBELL);
170                 if (ft1000dev->fcodeldr) {
171                         DEBUG(" get_handshake: fcodeldr is %d\n",
172                                 ft1000dev->fcodeldr);
173                         ft1000dev->fcodeldr = 0;
174                         status = check_usb_db(ft1000dev);
175                         if (status != STATUS_SUCCESS) {
176                                 DEBUG("get_handshake: check_usb_db failed\n");
177                                 status = STATUS_FAILURE;
178                                 break;
179                         }
180                         status = ft1000_write_register(ft1000dev,
181                                         FT1000_DB_DNLD_RX,
182                                         FT1000_REG_DOORBELL);
183                 }
184
185                 status = ft1000_read_dpram16(ft1000dev,
186                                 DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1);
187                 handshake = ntohs(handshake);
188
189                 if (status)
190                         return HANDSHAKE_TIMEOUT_VALUE;
191
192                 if ((handshake == expected_value) ||
193                     (handshake == HANDSHAKE_RESET_VALUE_USB)) {
194                         return handshake;
195                 } else  {
196                         loopcnt++;
197                         msleep(10);
198                 }
199         }
200
201         return HANDSHAKE_TIMEOUT_VALUE;
202 }
203
204 /* write the handshake value to the handshake location */
205 static void put_handshake(struct ft1000_usb *ft1000dev,u16 handshake_value)
206 {
207         u32 tempx;
208         u16 tempword;
209         int status;
210
211         tempx = (u32)handshake_value;
212         tempx = ntohl(tempx);
213
214         tempword = (u16)(tempx & 0xffff);
215         status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC,
216                                         tempword, 0);
217         tempword = (u16)(tempx >> 16);
218         status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC,
219                                         tempword, 1);
220         status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX,
221                                         FT1000_REG_DOORBELL);
222 }
223
224 static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value)
225 {
226         u16 handshake;
227         int loopcnt;
228         u16 temp;
229         int status = 0;
230
231         loopcnt = 0;
232         handshake = 0;
233
234         while (loopcnt < 100) {
235                 if (ft1000dev->usbboot == 2) {
236                         status = ft1000_read_dpram32(ft1000dev, 0,
237                                         (u8 *)&(ft1000dev->tempbuf[0]), 64);
238                         for (temp = 0; temp < 16; temp++) {
239                                 DEBUG("tempbuf %d = 0x%x\n", temp,
240                                         ft1000dev->tempbuf[temp]);
241                         }
242                         status = ft1000_read_dpram16(ft1000dev,
243                                                 DWNLD_MAG1_HANDSHAKE_LOC,
244                                                 (u8 *)&handshake, 1);
245                         DEBUG("handshake from read_dpram16 = 0x%x\n",
246                                 handshake);
247                         if (ft1000dev->dspalive == ft1000dev->tempbuf[6]) {
248                                 handshake = 0;
249                         } else {
250                                 handshake = ft1000dev->tempbuf[1];
251                                 ft1000dev->dspalive =
252                                                 ft1000dev->tempbuf[6];
253                         }
254                 } else {
255                         status = ft1000_read_dpram16(ft1000dev,
256                                                 DWNLD_MAG1_HANDSHAKE_LOC,
257                                                 (u8 *)&handshake, 1);
258                 }
259
260                 loopcnt++;
261                 msleep(10);
262                 handshake = ntohs(handshake);
263                 if ((handshake == expected_value) ||
264                     (handshake == HANDSHAKE_RESET_VALUE_USB))
265                         return handshake;
266         }
267
268         return HANDSHAKE_TIMEOUT_VALUE;
269 }
270
271 static void put_handshake_usb(struct ft1000_usb *ft1000dev,u16 handshake_value)
272 {
273         int i;
274
275         for (i=0; i<1000; i++);
276 }
277
278 static u16 get_request_type(struct ft1000_usb *ft1000dev)
279 {
280         u16 request_type;
281         int status;
282         u16 tempword;
283         u32 tempx;
284
285         if (ft1000dev->bootmode == 1) {
286                 status = fix_ft1000_read_dpram32(ft1000dev,
287                                 DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx);
288                 tempx = ntohl(tempx);
289         } else {
290                 tempx = 0;
291                 status = ft1000_read_dpram16(ft1000dev,
292                                 DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1);
293                 tempx |= (tempword << 16);
294                 tempx = ntohl(tempx);
295         }
296         request_type = (u16)tempx;
297
298         return request_type;
299 }
300
301 static u16 get_request_type_usb(struct ft1000_usb *ft1000dev)
302 {
303         u16 request_type;
304         int status;
305         u16 tempword;
306         u32 tempx;
307
308         if (ft1000dev->bootmode == 1) {
309                 status = fix_ft1000_read_dpram32(ft1000dev,
310                                 DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx);
311                 tempx = ntohl(tempx);
312         } else {
313                 if (ft1000dev->usbboot == 2) {
314                         tempx = ft1000dev->tempbuf[2];
315                         tempword = ft1000dev->tempbuf[3];
316                 } else {
317                         tempx = 0;
318                         status = ft1000_read_dpram16(ft1000dev,
319                                         DWNLD_MAG1_TYPE_LOC,
320                                         (u8 *)&tempword, 1);
321                 }
322                 tempx |= (tempword << 16);
323                 tempx = ntohl(tempx);
324         }
325         request_type = (u16)tempx;
326
327         return request_type;
328 }
329
330 static long get_request_value(struct ft1000_usb *ft1000dev)
331 {
332         u32 value;
333         u16 tempword;
334         int status;
335
336         if (ft1000dev->bootmode == 1) {
337                 status = fix_ft1000_read_dpram32(ft1000dev,
338                                 DWNLD_MAG1_SIZE_LOC, (u8 *)&value);
339                 value = ntohl(value);
340         } else  {
341                 status = ft1000_read_dpram16(ft1000dev,
342                                 DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0);
343                 value = tempword;
344                 status = ft1000_read_dpram16(ft1000dev,
345                                 DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1);
346                 value |= (tempword << 16);
347                 value = ntohl(value);
348         }
349
350         return value;
351 }
352
353
354 /* writes a value to DWNLD_MAG1_SIZE_LOC */
355 static void put_request_value(struct ft1000_usb *ft1000dev, long lvalue)
356 {
357         u32    tempx;
358         int    status;
359
360         tempx = ntohl(lvalue);
361         status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC,
362                                           (u8 *)&tempx);
363 }
364
365
366
367 /* returns the checksum of the pseudo header */
368 static u16 hdr_checksum(struct pseudo_hdr *pHdr)
369 {
370         u16   *usPtr = (u16 *)pHdr;
371         u16   chksum;
372
373
374         chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^
375         usPtr[4]) ^ usPtr[5]) ^ usPtr[6]);
376
377         return chksum;
378 }
379
380 static int check_buffers(u16 *buff_w, u16 *buff_r, int len, int offset)
381 {
382         int i;
383
384         for (i = 0; i < len; i++) {
385                 if (buff_w[i] != buff_r[i + offset])
386                         return -EREMOTEIO;
387         }
388
389         return 0;
390 }
391
392 static int write_dpram32_and_check(struct ft1000_usb *ft1000dev,
393                 u16 tempbuffer[], u16 dpram)
394 {
395         int status;
396         u16 resultbuffer[64];
397         int i;
398
399         for (i = 0; i < 10; i++) {
400                 status = ft1000_write_dpram32(ft1000dev, dpram,
401                                 (u8 *)&tempbuffer[0], 64);
402                 if (status == 0) {
403                         /* Work around for ASIC bit stuffing problem. */
404                         if ((tempbuffer[31] & 0xfe00) == 0xfe00) {
405                                 status = ft1000_write_dpram32(ft1000dev,
406                                                 dpram+12, (u8 *)&tempbuffer[24],
407                                                 64);
408                         }
409                         /* Let's check the data written */
410                         status = ft1000_read_dpram32(ft1000dev, dpram,
411                                         (u8 *)&resultbuffer[0], 64);
412                         if ((tempbuffer[31] & 0xfe00) == 0xfe00) {
413                                 if (check_buffers(tempbuffer, resultbuffer, 28,
414                                                         0)) {
415                                         DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n");
416                                         usleep_range(9000, 11000);
417                                         break;
418                                 }
419                                 status = ft1000_read_dpram32(ft1000dev,
420                                                 dpram+12,
421                                                 (u8 *)&resultbuffer[0], 64);
422
423                                 if (check_buffers(tempbuffer, resultbuffer, 16,
424                                                         24)) {
425                                         DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n");
426                                         usleep_range(9000, 11000);
427                                         break;
428                                 }
429                         } else {
430                                 if (check_buffers(tempbuffer, resultbuffer, 32,
431                                                         0)) {
432                                         DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n");
433                                         usleep_range(9000, 11000);
434                                         break;
435                                 }
436                         }
437                         if (status == 0)
438                                 break;
439                 }
440         }
441         return status;
442 }
443
444 /* writes a block of DSP image to DPRAM
445  * Parameters:  struct ft1000_usb  - device structure
446  *              u16 **pUsFile - DSP image file pointer in u16
447  *              u8  **pUcFile - DSP image file pointer in u8
448  *              long word_length - length of the buffer to be written to DPRAM
449  */
450 static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile,
451                 long word_length)
452 {
453         int status = STATUS_SUCCESS;
454         u16 dpram;
455         int loopcnt, i;
456         u16 tempword;
457         u16 tempbuffer[64];
458
459         /*DEBUG("FT1000:download:start word_length = %d\n",(int)word_length); */
460         dpram = (u16)DWNLD_MAG1_PS_HDR_LOC;
461         tempword = *(*pUsFile);
462         (*pUsFile)++;
463         status = ft1000_write_dpram16(ft1000dev, dpram, tempword, 0);
464         tempword = *(*pUsFile);
465         (*pUsFile)++;
466         status = ft1000_write_dpram16(ft1000dev, dpram++, tempword, 1);
467
468         *pUcFile = *pUcFile + 4;
469         word_length--;
470         tempword = (u16)word_length;
471         word_length = (word_length / 16) + 1;
472         for (; word_length > 0; word_length--) { /* In words */
473                 loopcnt = 0;
474                 for (i = 0; i < 32; i++) {
475                         if (tempword != 0) {
476                                 tempbuffer[i++] = *(*pUsFile);
477                                 (*pUsFile)++;
478                                 tempbuffer[i] = *(*pUsFile);
479                                 (*pUsFile)++;
480                                 *pUcFile = *pUcFile + 4;
481                                 loopcnt++;
482                                 tempword--;
483                         } else {
484                                 tempbuffer[i++] = 0;
485                                 tempbuffer[i] = 0;
486                         }
487                 }
488
489                 /*DEBUG("write_blk: loopcnt is %d\n", loopcnt); */
490                 /*DEBUG("write_blk: bootmode = %d\n", bootmode); */
491                 /*DEBUG("write_blk: dpram = %x\n", dpram); */
492                 if (ft1000dev->bootmode == 0) {
493                         if (dpram >= 0x3F4)
494                                 status = ft1000_write_dpram32(ft1000dev, dpram,
495                                                 (u8 *)&tempbuffer[0], 8);
496                         else
497                                 status = ft1000_write_dpram32(ft1000dev, dpram,
498                                                 (u8 *)&tempbuffer[0], 64);
499                 } else {
500                         status = write_dpram32_and_check(ft1000dev, tempbuffer,
501                                         dpram);
502                         if (status != STATUS_SUCCESS) {
503                                 DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]);
504                                 break;
505                         }
506                 }
507                 dpram = dpram + loopcnt;
508         }
509         return status;
510 }
511
512 static void usb_dnld_complete (struct urb *urb)
513 {
514     //DEBUG("****** usb_dnld_complete\n");
515 }
516
517 /* writes a block of DSP image to DPRAM
518  * Parameters:  struct ft1000_usb  - device structure
519  *              u16 **pUsFile - DSP image file pointer in u16
520  *              u8  **pUcFile - DSP image file pointer in u8
521  *              long word_length - length of the buffer to be written to DPRAM
522  */
523 static int write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile,
524                           u8 **pUcFile, long word_length)
525 {
526         int Status = STATUS_SUCCESS;
527         int byte_length;
528
529         byte_length = word_length * 4;
530
531         if (byte_length && ((byte_length % 64) == 0))
532                 byte_length += 4;
533
534         if (byte_length < 64)
535                 byte_length = 68;
536
537         usb_init_urb(ft1000dev->tx_urb);
538         memcpy(ft1000dev->tx_buf, *pUcFile, byte_length);
539         usb_fill_bulk_urb(ft1000dev->tx_urb,
540                           ft1000dev->dev,
541                           usb_sndbulkpipe(ft1000dev->dev,
542                                           ft1000dev->bulk_out_endpointAddr),
543                           ft1000dev->tx_buf, byte_length, usb_dnld_complete,
544                           (void *)ft1000dev);
545
546         usb_submit_urb(ft1000dev->tx_urb, GFP_ATOMIC);
547
548         *pUsFile = *pUsFile + (word_length << 1);
549         *pUcFile = *pUcFile + (word_length << 2);
550
551         return Status;
552 }
553
554 static int scram_start_dwnld(struct ft1000_usb *ft1000dev, u16 *hshake,
555                 u32 *state)
556 {
557         int status = 0;
558
559         DEBUG("FT1000:STATE_START_DWNLD\n");
560         if (ft1000dev->usbboot)
561                 *hshake = get_handshake_usb(ft1000dev, HANDSHAKE_DSP_BL_READY);
562         else
563                 *hshake = get_handshake(ft1000dev, HANDSHAKE_DSP_BL_READY);
564         if (*hshake == HANDSHAKE_DSP_BL_READY) {
565                 DEBUG("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
566                 put_handshake(ft1000dev, HANDSHAKE_DRIVER_READY);
567         } else if (*hshake == HANDSHAKE_TIMEOUT_VALUE) {
568                 status = -ETIMEDOUT;
569         } else {
570                 DEBUG("FT1000:download:Download error: Handshake failed\n");
571                 status = -ENETRESET;
572         }
573         *state = STATE_BOOT_DWNLD;
574         return status;
575 }
576
577 static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file,
578                  u8 **c_file, const u8 *endpoint, bool boot_case)
579 {
580         long word_length;
581         int status = 0;
582
583         /*DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");i*/
584         word_length = get_request_value(ft1000dev);
585         /*DEBUG("FT1000:word_length = 0x%x\n", (int)word_length); */
586         /*NdisMSleep (100); */
587         if (word_length > MAX_LENGTH) {
588                 DEBUG("FT1000:download:Download error: Max length exceeded\n");
589                 return STATUS_FAILURE;
590         }
591         if ((word_length * 2 + (long)c_file) > (long)endpoint) {
592                 /* Error, beyond boot code range.*/
593                 DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n", (int)word_length);
594                 return STATUS_FAILURE;
595         }
596         if (word_length & 0x1)
597                 word_length++;
598         word_length = word_length / 2;
599
600         if (boot_case) {
601                 status = write_blk(ft1000dev, s_file, c_file, word_length);
602                 /*DEBUG("write_blk returned %d\n", status); */
603         } else {
604                 write_blk_fifo(ft1000dev, s_file, c_file, word_length);
605                 if (ft1000dev->usbboot == 0)
606                         ft1000dev->usbboot++;
607                 if (ft1000dev->usbboot == 1)
608                         ft1000_write_dpram16(ft1000dev,
609                                         DWNLD_MAG1_PS_HDR_LOC, 0, 0);
610         }
611         return status;
612 }
613
614 /* Scramble downloader for Harley based ASIC via USB interface */
615 int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
616                 u32 FileLength)
617 {
618         int status = STATUS_SUCCESS;
619         u32 state;
620         u16 handshake;
621         struct pseudo_hdr *pseudo_header;
622         u16 pseudo_header_len;
623         long word_length;
624         u16 request;
625         u16 temp;
626
627         struct dsp_file_hdr *file_hdr;
628         struct dsp_image_info *dsp_img_info = NULL;
629         long requested_version;
630         bool correct_version;
631         struct drv_msg *mailbox_data;
632         u16 *data = NULL;
633         u16 *s_file = NULL;
634         u8 *c_file = NULL;
635         u8 *boot_end = NULL, *code_end = NULL;
636         int image;
637         long loader_code_address, loader_code_size = 0;
638         long run_address = 0, run_size = 0;
639
640         u32 templong;
641         u32 image_chksum = 0;
642
643         u16 dpram = 0;
644         u8 *pbuffer;
645         struct prov_record *pprov_record;
646         struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
647
648         DEBUG("Entered   scram_dnldr...\n");
649
650         ft1000dev->fcodeldr = 0;
651         ft1000dev->usbboot = 0;
652         ft1000dev->dspalive = 0xffff;
653
654         //
655         // Get version id of file, at first 4 bytes of file, for newer files.
656         //
657
658         state = STATE_START_DWNLD;
659
660         file_hdr = (struct dsp_file_hdr *)pFileStart;
661
662         ft1000_write_register(ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK);
663
664         s_file = (u16 *) (pFileStart + file_hdr->loader_offset);
665         c_file = (u8 *) (pFileStart + file_hdr->loader_offset);
666
667         boot_end = (u8 *) (pFileStart + file_hdr->loader_code_end);
668
669         loader_code_address = file_hdr->loader_code_address;
670         loader_code_size = file_hdr->loader_code_size;
671         correct_version = false;
672
673         while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) {
674                 switch (state) {
675                 case STATE_START_DWNLD:
676                         status = scram_start_dwnld(ft1000dev, &handshake,
677                                                    &state);
678                         break;
679
680                 case STATE_BOOT_DWNLD:
681                         DEBUG("FT1000:STATE_BOOT_DWNLD\n");
682                         ft1000dev->bootmode = 1;
683                         handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST);
684                         if (handshake == HANDSHAKE_REQUEST) {
685                                 /*
686                                  * Get type associated with the request.
687                                  */
688                                 request = get_request_type(ft1000dev);
689                                 switch (request) {
690                                 case REQUEST_RUN_ADDRESS:
691                                         DEBUG("FT1000:REQUEST_RUN_ADDRESS\n");
692                                         put_request_value(ft1000dev,
693                                                           loader_code_address);
694                                         break;
695                                 case REQUEST_CODE_LENGTH:
696                                         DEBUG("FT1000:REQUEST_CODE_LENGTH\n");
697                                         put_request_value(ft1000dev,
698                                                           loader_code_size);
699                                         break;
700                                 case REQUEST_DONE_BL:
701                                         DEBUG("FT1000:REQUEST_DONE_BL\n");
702                                         /* Reposition ptrs to beginning of code section */
703                                         s_file = (u16 *) (boot_end);
704                                         c_file = (u8 *) (boot_end);
705                                         //DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file);
706                                         //DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file);
707                                         state = STATE_CODE_DWNLD;
708                                         ft1000dev->fcodeldr = 1;
709                                         break;
710                                 case REQUEST_CODE_SEGMENT:
711                                         status = request_code_segment(ft1000dev,
712                                                         &s_file, &c_file,
713                                                         (const u8 *)boot_end,
714                                                         true);
715                                 break;
716                                 default:
717                                         DEBUG
718                                             ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",
719                                              request);
720                                         status = STATUS_FAILURE;
721                                         break;
722                                 }
723                                 if (ft1000dev->usbboot)
724                                         put_handshake_usb(ft1000dev,
725                                                           HANDSHAKE_RESPONSE);
726                                 else
727                                         put_handshake(ft1000dev,
728                                                       HANDSHAKE_RESPONSE);
729                         } else {
730                                 DEBUG
731                                     ("FT1000:download:Download error: Handshake failed\n");
732                                 status = STATUS_FAILURE;
733                         }
734
735                         break;
736
737                 case STATE_CODE_DWNLD:
738                         //DEBUG("FT1000:STATE_CODE_DWNLD\n");
739                         ft1000dev->bootmode = 0;
740                         if (ft1000dev->usbboot)
741                                 handshake =
742                                     get_handshake_usb(ft1000dev,
743                                                       HANDSHAKE_REQUEST);
744                         else
745                                 handshake =
746                                     get_handshake(ft1000dev, HANDSHAKE_REQUEST);
747                         if (handshake == HANDSHAKE_REQUEST) {
748                                 /*
749                                  * Get type associated with the request.
750                                  */
751                                 if (ft1000dev->usbboot)
752                                         request =
753                                             get_request_type_usb(ft1000dev);
754                                 else
755                                         request = get_request_type(ft1000dev);
756                                 switch (request) {
757                                 case REQUEST_FILE_CHECKSUM:
758                                         DEBUG
759                                             ("FT1000:download:image_chksum = 0x%8x\n",
760                                              image_chksum);
761                                         put_request_value(ft1000dev,
762                                                           image_chksum);
763                                         break;
764                                 case REQUEST_RUN_ADDRESS:
765                                         DEBUG
766                                             ("FT1000:download:  REQUEST_RUN_ADDRESS\n");
767                                         if (correct_version) {
768                                                 DEBUG
769                                                     ("FT1000:download:run_address = 0x%8x\n",
770                                                      (int)run_address);
771                                                 put_request_value(ft1000dev,
772                                                                   run_address);
773                                         } else {
774                                                 DEBUG
775                                                     ("FT1000:download:Download error: Got Run address request before image offset request.\n");
776                                                 status = STATUS_FAILURE;
777                                                 break;
778                                         }
779                                         break;
780                                 case REQUEST_CODE_LENGTH:
781                                         DEBUG
782                                             ("FT1000:download:REQUEST_CODE_LENGTH\n");
783                                         if (correct_version) {
784                                                 DEBUG
785                                                     ("FT1000:download:run_size = 0x%8x\n",
786                                                      (int)run_size);
787                                                 put_request_value(ft1000dev,
788                                                                   run_size);
789                                         } else {
790                                                 DEBUG
791                                                     ("FT1000:download:Download error: Got Size request before image offset request.\n");
792                                                 status = STATUS_FAILURE;
793                                                 break;
794                                         }
795                                         break;
796                                 case REQUEST_DONE_CL:
797                                         ft1000dev->usbboot = 3;
798                                         /* Reposition ptrs to beginning of provisioning section */
799                                         s_file =
800                                             (u16 *) (pFileStart +
801                                                      file_hdr->commands_offset);
802                                         c_file =
803                                             (u8 *) (pFileStart +
804                                                     file_hdr->commands_offset);
805                                         state = STATE_DONE_DWNLD;
806                                         break;
807                                 case REQUEST_CODE_SEGMENT:
808                                         //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n");
809                                         if (!correct_version) {
810                                                 DEBUG
811                                                     ("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
812                                                 status = STATUS_FAILURE;
813                                                 break;
814                                         }
815
816                                         status = request_code_segment(ft1000dev,
817                                                         &s_file, &c_file,
818                                                         (const u8 *)code_end,
819                                                         false);
820
821                                         break;
822
823                                 case REQUEST_MAILBOX_DATA:
824                                         DEBUG
825                                             ("FT1000:download: REQUEST_MAILBOX_DATA\n");
826                                         // Convert length from byte count to word count. Make sure we round up.
827                                         word_length =
828                                             (long)(pft1000info->DSPInfoBlklen +
829                                                    1) / 2;
830                                         put_request_value(ft1000dev,
831                                                           word_length);
832                                         mailbox_data =
833                                             (struct drv_msg *)&(pft1000info->
834                                                                 DSPInfoBlk[0]);
835                                         /*
836                                          * Position ASIC DPRAM auto-increment pointer.
837                                          */
838
839                                         data = (u16 *) & mailbox_data->data[0];
840                                         dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
841                                         if (word_length & 0x1)
842                                                 word_length++;
843
844                                         word_length = (word_length / 2);
845
846                                         for (; word_length > 0; word_length--) {        /* In words */
847
848                                                 templong = *data++;
849                                                 templong |= (*data++ << 16);
850                                                 status =
851                                                     fix_ft1000_write_dpram32
852                                                     (ft1000dev, dpram++,
853                                                      (u8 *) & templong);
854
855                                         }
856                                         break;
857
858                                 case REQUEST_VERSION_INFO:
859                                         DEBUG
860                                             ("FT1000:download:REQUEST_VERSION_INFO\n");
861                                         word_length =
862                                             file_hdr->version_data_size;
863                                         put_request_value(ft1000dev,
864                                                           word_length);
865                                         /*
866                                          * Position ASIC DPRAM auto-increment pointer.
867                                          */
868
869                                         s_file =
870                                             (u16 *) (pFileStart +
871                                                      file_hdr->
872                                                      version_data_offset);
873
874                                         dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
875                                         if (word_length & 0x1)
876                                                 word_length++;
877
878                                         word_length = (word_length / 2);
879
880                                         for (; word_length > 0; word_length--) {        /* In words */
881
882                                                 templong = ntohs(*s_file++);
883                                                 temp = ntohs(*s_file++);
884                                                 templong |= (temp << 16);
885                                                 status =
886                                                     fix_ft1000_write_dpram32
887                                                     (ft1000dev, dpram++,
888                                                      (u8 *) &templong);
889
890                                         }
891                                         break;
892
893                                 case REQUEST_CODE_BY_VERSION:
894                                         DEBUG
895                                             ("FT1000:download:REQUEST_CODE_BY_VERSION\n");
896                                         correct_version = false;
897                                         requested_version =
898                                             get_request_value(ft1000dev);
899
900                                         dsp_img_info =
901                                             (struct dsp_image_info *)(pFileStart
902                                                                       +
903                                                                       sizeof
904                                                                       (struct
905                                                                        dsp_file_hdr));
906
907                                         for (image = 0;
908                                              image < file_hdr->nDspImages;
909                                              image++) {
910
911                                                 if (dsp_img_info->version ==
912                                                     requested_version) {
913                                                         correct_version = true;
914                                                         DEBUG
915                                                             ("FT1000:download: correct_version is TRUE\n");
916                                                         s_file =
917                                                             (u16 *) (pFileStart
918                                                                      +
919                                                                      dsp_img_info->
920                                                                      begin_offset);
921                                                         c_file =
922                                                             (u8 *) (pFileStart +
923                                                                     dsp_img_info->
924                                                                     begin_offset);
925                                                         code_end =
926                                                             (u8 *) (pFileStart +
927                                                                     dsp_img_info->
928                                                                     end_offset);
929                                                         run_address =
930                                                             dsp_img_info->
931                                                             run_address;
932                                                         run_size =
933                                                             dsp_img_info->
934                                                             image_size;
935                                                         image_chksum =
936                                                             (u32) dsp_img_info->
937                                                             checksum;
938                                                         break;
939                                                 }
940                                                 dsp_img_info++;
941
942                                         }       //end of for
943
944                                         if (!correct_version) {
945                                                 /*
946                                                  * Error, beyond boot code range.
947                                                  */
948                                                 DEBUG
949                                                     ("FT1000:download:Download error: Bad Version Request = 0x%x.\n",
950                                                      (int)requested_version);
951                                                 status = STATUS_FAILURE;
952                                                 break;
953                                         }
954                                         break;
955
956                                 default:
957                                         DEBUG
958                                             ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",
959                                              request);
960                                         status = STATUS_FAILURE;
961                                         break;
962                                 }
963                                 if (ft1000dev->usbboot)
964                                         put_handshake_usb(ft1000dev,
965                                                           HANDSHAKE_RESPONSE);
966                                 else
967                                         put_handshake(ft1000dev,
968                                                       HANDSHAKE_RESPONSE);
969                         } else {
970                                 DEBUG
971                                     ("FT1000:download:Download error: Handshake failed\n");
972                                 status = STATUS_FAILURE;
973                         }
974
975                         break;
976
977                 case STATE_DONE_DWNLD:
978                         DEBUG("FT1000:download:Code loader is done...\n");
979                         state = STATE_SECTION_PROV;
980                         break;
981
982                 case STATE_SECTION_PROV:
983                         DEBUG("FT1000:download:STATE_SECTION_PROV\n");
984                         pseudo_header = (struct pseudo_hdr *)c_file;
985
986                         if (pseudo_header->checksum ==
987                             hdr_checksum(pseudo_header)) {
988                                 if (pseudo_header->portdest !=
989                                     0x80 /* Dsp OAM */) {
990                                         state = STATE_DONE_PROV;
991                                         break;
992                                 }
993                                 pseudo_header_len = ntohs(pseudo_header->length);       /* Byte length for PROV records */
994
995                                 /* Get buffer for provisioning data */
996                                 pbuffer =
997                                     kmalloc((pseudo_header_len +
998                                              sizeof(struct pseudo_hdr)),
999                                             GFP_ATOMIC);
1000                                 if (pbuffer) {
1001                                         memcpy(pbuffer, (void *)c_file,
1002                                                (u32) (pseudo_header_len +
1003                                                       sizeof(struct
1004                                                              pseudo_hdr)));
1005                                         // link provisioning data
1006                                         pprov_record =
1007                                             kmalloc(sizeof(struct prov_record),
1008                                                     GFP_ATOMIC);
1009                                         if (pprov_record) {
1010                                                 pprov_record->pprov_data =
1011                                                     pbuffer;
1012                                                 list_add_tail(&pprov_record->
1013                                                               list,
1014                                                               &pft1000info->
1015                                                               prov_list);
1016                                                 // Move to next entry if available
1017                                                 c_file =
1018                                                     (u8 *) ((unsigned long)
1019                                                             c_file +
1020                                                             (u32) ((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr));
1021                                                 if ((unsigned long)(c_file) -
1022                                                     (unsigned long)(pFileStart)
1023                                                     >=
1024                                                     (unsigned long)FileLength) {
1025                                                         state = STATE_DONE_FILE;
1026                                                 }
1027                                         } else {
1028                                                 kfree(pbuffer);
1029                                                 status = STATUS_FAILURE;
1030                                         }
1031                                 } else {
1032                                         status = STATUS_FAILURE;
1033                                 }
1034                         } else {
1035                                 /* Checksum did not compute */
1036                                 status = STATUS_FAILURE;
1037                         }
1038                         DEBUG
1039                             ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n",
1040                              state, status);
1041                         break;
1042
1043                 case STATE_DONE_PROV:
1044                         DEBUG("FT1000:download:STATE_DONE_PROV\n");
1045                         state = STATE_DONE_FILE;
1046                         break;
1047
1048                 default:
1049                         status = STATUS_FAILURE;
1050                         break;
1051                 }               /* End Switch */
1052
1053                 if (status != STATUS_SUCCESS)
1054                         break;
1055
1056 /****
1057       // Check if Card is present
1058       status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
1059       if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
1060           break;
1061       }
1062
1063       status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
1064       if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
1065           break;
1066       }
1067 ****/
1068
1069         }                       /* End while */
1070
1071         DEBUG("Download exiting with status = 0x%8x\n", status);
1072         ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX,
1073                               FT1000_REG_DOORBELL);
1074
1075         return status;
1076 }