2 * CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
4 * This file is part of Express Card USB Driver
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/netdevice.h>
10 #include <linux/etherdevice.h>
11 #include <linux/usb.h>
12 #include <linux/vmalloc.h>
13 #include "ft1000_usb.h"
16 #define DWNLD_HANDSHAKE_LOC 0x02
17 #define DWNLD_TYPE_LOC 0x04
18 #define DWNLD_SIZE_MSW_LOC 0x06
19 #define DWNLD_SIZE_LSW_LOC 0x08
20 #define DWNLD_PS_HDR_LOC 0x0A
22 #define MAX_DSP_WAIT_LOOPS 40
23 #define DSP_WAIT_SLEEP_TIME 1000 /* 1 millisecond */
24 #define DSP_WAIT_DISPATCH_LVL 50 /* 50 usec */
26 #define HANDSHAKE_TIMEOUT_VALUE 0xF1F1
27 #define HANDSHAKE_RESET_VALUE 0xFEFE /* When DSP requests startover */
28 #define HANDSHAKE_RESET_VALUE_USB 0xFE7E /* When DSP requests startover */
29 #define HANDSHAKE_DSP_BL_READY 0xFEFE /* At start DSP writes this when bootloader ready */
30 #define HANDSHAKE_DSP_BL_READY_USB 0xFE7E /* At start DSP writes this when bootloader ready */
31 #define HANDSHAKE_DRIVER_READY 0xFFFF /* Driver writes after receiving 0xFEFE */
32 #define HANDSHAKE_SEND_DATA 0x0000 /* DSP writes this when ready for more data */
34 #define HANDSHAKE_REQUEST 0x0001 /* Request from DSP */
35 #define HANDSHAKE_RESPONSE 0x0000 /* Satisfied DSP request */
37 #define REQUEST_CODE_LENGTH 0x0000
38 #define REQUEST_RUN_ADDRESS 0x0001
39 #define REQUEST_CODE_SEGMENT 0x0002 /* In WORD count */
40 #define REQUEST_DONE_BL 0x0003
41 #define REQUEST_DONE_CL 0x0004
42 #define REQUEST_VERSION_INFO 0x0005
43 #define REQUEST_CODE_BY_VERSION 0x0006
44 #define REQUEST_MAILBOX_DATA 0x0007
45 #define REQUEST_FILE_CHECKSUM 0x0008
47 #define STATE_START_DWNLD 0x01
48 #define STATE_BOOT_DWNLD 0x02
49 #define STATE_CODE_DWNLD 0x03
50 #define STATE_DONE_DWNLD 0x04
51 #define STATE_SECTION_PROV 0x05
52 #define STATE_DONE_PROV 0x06
53 #define STATE_DONE_FILE 0x07
55 #define MAX_LENGTH 0x7f0
57 /* Temporary download mechanism for Magnemite */
58 #define DWNLD_MAG_TYPE_LOC 0x00
59 #define DWNLD_MAG_LEN_LOC 0x01
60 #define DWNLD_MAG_ADDR_LOC 0x02
61 #define DWNLD_MAG_CHKSUM_LOC 0x03
62 #define DWNLD_MAG_VAL_LOC 0x04
64 #define HANDSHAKE_MAG_DSP_BL_READY 0xFEFE0000 /* At start DSP writes this when bootloader ready */
65 #define HANDSHAKE_MAG_DSP_ENTRY 0x01000000 /* Dsp writes this to request for entry address */
66 #define HANDSHAKE_MAG_DSP_DATA 0x02000000 /* Dsp writes this to request for data block */
67 #define HANDSHAKE_MAG_DSP_DONE 0x03000000 /* Dsp writes this to indicate download done */
69 #define HANDSHAKE_MAG_DRV_READY 0xFFFF0000 /* Driver writes this to indicate ready to download */
70 #define HANDSHAKE_MAG_DRV_DATA 0x02FECDAB /* Driver writes this to indicate data available to DSP */
71 #define HANDSHAKE_MAG_DRV_ENTRY 0x01FECDAB /* Driver writes this to indicate entry point to DSP */
73 #define HANDSHAKE_MAG_TIMEOUT_VALUE 0xF1F1
76 /* New Magnemite downloader */
77 #define DWNLD_MAG1_HANDSHAKE_LOC 0x00
78 #define DWNLD_MAG1_TYPE_LOC 0x01
79 #define DWNLD_MAG1_SIZE_LOC 0x02
80 #define DWNLD_MAG1_PS_HDR_LOC 0x03
83 long version_id
; /* Version ID of this image format. */
84 long package_id
; /* Package ID of code release. */
85 long build_date
; /* Date/time stamp when file was built. */
86 long commands_offset
; /* Offset to attached commands in Pseudo Hdr format. */
87 long loader_offset
; /* Offset to bootloader code. */
88 long loader_code_address
; /* Start address of bootloader. */
89 long loader_code_end
; /* Where bootloader code ends. */
90 long loader_code_size
;
91 long version_data_offset
; /* Offset were scrambled version data begins. */
92 long version_data_size
; /* Size, in words, of scrambled version data. */
93 long nDspImages
; /* Number of DSP images in file. */
97 struct dsp_image_info
{
98 long coff_date
; /* Date/time when DSP Coff image was built. */
99 long begin_offset
; /* Offset in file where image begins. */
100 long end_offset
; /* Offset in file where image begins. */
101 long run_address
; /* On chip Start address of DSP code. */
102 long image_size
; /* Size of image. */
103 long version
; /* Embedded version # of DSP code. */
104 unsigned short checksum
; /* DSP File checksum */
109 /* checks if the doorbell register is cleared */
110 static int check_usb_db(struct ft1000_usb
*ft1000dev
)
118 while (loopcnt
< 10) {
119 status
= ft1000_read_register(ft1000dev
, &temp
,
120 FT1000_REG_DOORBELL
);
121 DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n",
124 DEBUG("FT1000:Got checkusb doorbell\n");
125 status
= ft1000_write_register(ft1000dev
, 0x0080,
126 FT1000_REG_DOORBELL
);
127 status
= ft1000_write_register(ft1000dev
, 0x0100,
128 FT1000_REG_DOORBELL
);
129 status
= ft1000_write_register(ft1000dev
, 0x8000,
130 FT1000_REG_DOORBELL
);
140 while (loopcnt
< 20) {
141 status
= ft1000_read_register(ft1000dev
, &temp
,
142 FT1000_REG_DOORBELL
);
143 DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp
);
148 DEBUG("check_usb_db: door bell is cleared, return 0\n");
156 /* gets the handshake and compares it with the expected value */
157 static u16
get_handshake(struct ft1000_usb
*ft1000dev
, u16 expected_value
)
165 while (loopcnt
< 100) {
166 /* Need to clear downloader doorbell if Hartley ASIC */
167 status
= ft1000_write_register(ft1000dev
, FT1000_DB_DNLD_RX
,
168 FT1000_REG_DOORBELL
);
169 if (ft1000dev
->fcodeldr
) {
170 DEBUG(" get_handshake: fcodeldr is %d\n",
171 ft1000dev
->fcodeldr
);
172 ft1000dev
->fcodeldr
= 0;
173 status
= check_usb_db(ft1000dev
);
175 DEBUG("get_handshake: check_usb_db failed\n");
178 status
= ft1000_write_register(ft1000dev
,
180 FT1000_REG_DOORBELL
);
183 status
= ft1000_read_dpram16(ft1000dev
,
184 DWNLD_MAG1_HANDSHAKE_LOC
, (u8
*)&handshake
, 1);
185 handshake
= ntohs(handshake
);
188 return HANDSHAKE_TIMEOUT_VALUE
;
190 if ((handshake
== expected_value
) ||
191 (handshake
== HANDSHAKE_RESET_VALUE_USB
)) {
199 return HANDSHAKE_TIMEOUT_VALUE
;
202 /* write the handshake value to the handshake location */
203 static void put_handshake(struct ft1000_usb
*ft1000dev
, u16 handshake_value
)
209 tempx
= (u32
)handshake_value
;
210 tempx
= ntohl(tempx
);
212 tempword
= (u16
)(tempx
& 0xffff);
213 status
= ft1000_write_dpram16(ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
,
215 tempword
= (u16
)(tempx
>> 16);
216 status
= ft1000_write_dpram16(ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
,
218 status
= ft1000_write_register(ft1000dev
, FT1000_DB_DNLD_TX
,
219 FT1000_REG_DOORBELL
);
222 static u16
get_handshake_usb(struct ft1000_usb
*ft1000dev
, u16 expected_value
)
232 while (loopcnt
< 100) {
233 if (ft1000dev
->usbboot
== 2) {
234 status
= ft1000_read_dpram32(ft1000dev
, 0,
235 (u8
*)&(ft1000dev
->tempbuf
[0]), 64);
236 for (temp
= 0; temp
< 16; temp
++) {
237 DEBUG("tempbuf %d = 0x%x\n", temp
,
238 ft1000dev
->tempbuf
[temp
]);
240 status
= ft1000_read_dpram16(ft1000dev
,
241 DWNLD_MAG1_HANDSHAKE_LOC
,
242 (u8
*)&handshake
, 1);
243 DEBUG("handshake from read_dpram16 = 0x%x\n",
245 if (ft1000dev
->dspalive
== ft1000dev
->tempbuf
[6]) {
248 handshake
= ft1000dev
->tempbuf
[1];
249 ft1000dev
->dspalive
=
250 ft1000dev
->tempbuf
[6];
253 status
= ft1000_read_dpram16(ft1000dev
,
254 DWNLD_MAG1_HANDSHAKE_LOC
,
255 (u8
*)&handshake
, 1);
260 handshake
= ntohs(handshake
);
261 if ((handshake
== expected_value
) ||
262 (handshake
== HANDSHAKE_RESET_VALUE_USB
))
266 return HANDSHAKE_TIMEOUT_VALUE
;
269 static void put_handshake_usb(struct ft1000_usb
*ft1000dev
, u16 handshake_value
)
273 for (i
= 0; i
< 1000; i
++)
277 static u16
get_request_type(struct ft1000_usb
*ft1000dev
)
284 if (ft1000dev
->bootmode
== 1) {
285 status
= fix_ft1000_read_dpram32(ft1000dev
,
286 DWNLD_MAG1_TYPE_LOC
, (u8
*)&tempx
);
287 tempx
= ntohl(tempx
);
290 status
= ft1000_read_dpram16(ft1000dev
,
291 DWNLD_MAG1_TYPE_LOC
, (u8
*)&tempword
, 1);
292 tempx
|= (tempword
<< 16);
293 tempx
= ntohl(tempx
);
295 request_type
= (u16
)tempx
;
300 static u16
get_request_type_usb(struct ft1000_usb
*ft1000dev
)
307 if (ft1000dev
->bootmode
== 1) {
308 status
= fix_ft1000_read_dpram32(ft1000dev
,
309 DWNLD_MAG1_TYPE_LOC
, (u8
*)&tempx
);
310 tempx
= ntohl(tempx
);
312 if (ft1000dev
->usbboot
== 2) {
313 tempx
= ft1000dev
->tempbuf
[2];
314 tempword
= ft1000dev
->tempbuf
[3];
317 status
= ft1000_read_dpram16(ft1000dev
,
321 tempx
|= (tempword
<< 16);
322 tempx
= ntohl(tempx
);
324 request_type
= (u16
)tempx
;
329 static long get_request_value(struct ft1000_usb
*ft1000dev
)
335 if (ft1000dev
->bootmode
== 1) {
336 status
= fix_ft1000_read_dpram32(ft1000dev
,
337 DWNLD_MAG1_SIZE_LOC
, (u8
*)&value
);
338 value
= ntohl(value
);
340 status
= ft1000_read_dpram16(ft1000dev
,
341 DWNLD_MAG1_SIZE_LOC
, (u8
*)&tempword
, 0);
343 status
= ft1000_read_dpram16(ft1000dev
,
344 DWNLD_MAG1_SIZE_LOC
, (u8
*)&tempword
, 1);
345 value
|= (tempword
<< 16);
346 value
= ntohl(value
);
353 /* writes a value to DWNLD_MAG1_SIZE_LOC */
354 static void put_request_value(struct ft1000_usb
*ft1000dev
, long lvalue
)
359 tempx
= ntohl(lvalue
);
360 status
= fix_ft1000_write_dpram32(ft1000dev
, DWNLD_MAG1_SIZE_LOC
,
366 /* returns the checksum of the pseudo header */
367 static u16
hdr_checksum(struct pseudo_hdr
*pHdr
)
369 u16
*usPtr
= (u16
*)pHdr
;
373 chksum
= ((((((usPtr
[0] ^ usPtr
[1]) ^ usPtr
[2]) ^ usPtr
[3]) ^
374 usPtr
[4]) ^ usPtr
[5]) ^ usPtr
[6]);
379 static int check_buffers(u16
*buff_w
, u16
*buff_r
, int len
, int offset
)
383 for (i
= 0; i
< len
; i
++) {
384 if (buff_w
[i
] != buff_r
[i
+ offset
])
391 static int write_dpram32_and_check(struct ft1000_usb
*ft1000dev
,
392 u16 tempbuffer
[], u16 dpram
)
395 u16 resultbuffer
[64];
398 for (i
= 0; i
< 10; i
++) {
399 status
= ft1000_write_dpram32(ft1000dev
, dpram
,
400 (u8
*)&tempbuffer
[0], 64);
402 /* Work around for ASIC bit stuffing problem. */
403 if ((tempbuffer
[31] & 0xfe00) == 0xfe00) {
404 status
= ft1000_write_dpram32(ft1000dev
,
405 dpram
+12, (u8
*)&tempbuffer
[24],
408 /* Let's check the data written */
409 status
= ft1000_read_dpram32(ft1000dev
, dpram
,
410 (u8
*)&resultbuffer
[0], 64);
411 if ((tempbuffer
[31] & 0xfe00) == 0xfe00) {
412 if (check_buffers(tempbuffer
, resultbuffer
, 28,
414 DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n");
415 usleep_range(9000, 11000);
418 status
= ft1000_read_dpram32(ft1000dev
,
420 (u8
*)&resultbuffer
[0], 64);
422 if (check_buffers(tempbuffer
, resultbuffer
, 16,
424 DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n");
425 usleep_range(9000, 11000);
429 if (check_buffers(tempbuffer
, resultbuffer
, 32,
431 DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n");
432 usleep_range(9000, 11000);
443 /* writes a block of DSP image to DPRAM
444 * Parameters: struct ft1000_usb - device structure
445 * u16 **pUsFile - DSP image file pointer in u16
446 * u8 **pUcFile - DSP image file pointer in u8
447 * long word_length - length of the buffer to be written to DPRAM
449 static int write_blk(struct ft1000_usb
*ft1000dev
, u16
**pUsFile
, u8
**pUcFile
,
458 /*DEBUG("FT1000:download:start word_length = %d\n",(int)word_length); */
459 dpram
= (u16
)DWNLD_MAG1_PS_HDR_LOC
;
460 tempword
= *(*pUsFile
);
462 status
= ft1000_write_dpram16(ft1000dev
, dpram
, tempword
, 0);
463 tempword
= *(*pUsFile
);
465 status
= ft1000_write_dpram16(ft1000dev
, dpram
++, tempword
, 1);
467 *pUcFile
= *pUcFile
+ 4;
469 tempword
= (u16
)word_length
;
470 word_length
= (word_length
/ 16) + 1;
471 for (; word_length
> 0; word_length
--) { /* In words */
473 for (i
= 0; i
< 32; i
++) {
475 tempbuffer
[i
++] = *(*pUsFile
);
477 tempbuffer
[i
] = *(*pUsFile
);
479 *pUcFile
= *pUcFile
+ 4;
488 /*DEBUG("write_blk: loopcnt is %d\n", loopcnt); */
489 /*DEBUG("write_blk: bootmode = %d\n", bootmode); */
490 /*DEBUG("write_blk: dpram = %x\n", dpram); */
491 if (ft1000dev
->bootmode
== 0) {
493 status
= ft1000_write_dpram32(ft1000dev
, dpram
,
494 (u8
*)&tempbuffer
[0], 8);
496 status
= ft1000_write_dpram32(ft1000dev
, dpram
,
497 (u8
*)&tempbuffer
[0], 64);
499 status
= write_dpram32_and_check(ft1000dev
, tempbuffer
,
502 DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer
[31]);
506 dpram
= dpram
+ loopcnt
;
511 static void usb_dnld_complete(struct urb
*urb
)
513 /* DEBUG("****** usb_dnld_complete\n"); */
516 /* writes a block of DSP image to DPRAM
517 * Parameters: struct ft1000_usb - device structure
518 * u16 **pUsFile - DSP image file pointer in u16
519 * u8 **pUcFile - DSP image file pointer in u8
520 * long word_length - length of the buffer to be written to DPRAM
522 static int write_blk_fifo(struct ft1000_usb
*ft1000dev
, u16
**pUsFile
,
523 u8
**pUcFile
, long word_length
)
528 byte_length
= word_length
* 4;
530 if (byte_length
&& ((byte_length
% 64) == 0))
533 if (byte_length
< 64)
536 usb_init_urb(ft1000dev
->tx_urb
);
537 memcpy(ft1000dev
->tx_buf
, *pUcFile
, byte_length
);
538 usb_fill_bulk_urb(ft1000dev
->tx_urb
,
540 usb_sndbulkpipe(ft1000dev
->dev
,
541 ft1000dev
->bulk_out_endpointAddr
),
542 ft1000dev
->tx_buf
, byte_length
, usb_dnld_complete
,
545 usb_submit_urb(ft1000dev
->tx_urb
, GFP_ATOMIC
);
547 *pUsFile
= *pUsFile
+ (word_length
<< 1);
548 *pUcFile
= *pUcFile
+ (word_length
<< 2);
553 static int scram_start_dwnld(struct ft1000_usb
*ft1000dev
, u16
*hshake
,
558 DEBUG("FT1000:STATE_START_DWNLD\n");
559 if (ft1000dev
->usbboot
)
560 *hshake
= get_handshake_usb(ft1000dev
, HANDSHAKE_DSP_BL_READY
);
562 *hshake
= get_handshake(ft1000dev
, HANDSHAKE_DSP_BL_READY
);
563 if (*hshake
== HANDSHAKE_DSP_BL_READY
) {
564 DEBUG("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
565 put_handshake(ft1000dev
, HANDSHAKE_DRIVER_READY
);
566 } else if (*hshake
== HANDSHAKE_TIMEOUT_VALUE
) {
569 DEBUG("FT1000:download:Download error: Handshake failed\n");
572 *state
= STATE_BOOT_DWNLD
;
576 static int request_code_segment(struct ft1000_usb
*ft1000dev
, u16
**s_file
,
577 u8
**c_file
, const u8
*endpoint
, bool boot_case
)
582 /*DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");i*/
583 word_length
= get_request_value(ft1000dev
);
584 /*DEBUG("FT1000:word_length = 0x%x\n", (int)word_length); */
585 /*NdisMSleep (100); */
586 if (word_length
> MAX_LENGTH
) {
587 DEBUG("FT1000:download:Download error: Max length exceeded\n");
590 if ((word_length
* 2 + (long)c_file
) > (long)endpoint
) {
591 /* Error, beyond boot code range.*/
592 DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n", (int)word_length
);
595 if (word_length
& 0x1)
597 word_length
= word_length
/ 2;
600 status
= write_blk(ft1000dev
, s_file
, c_file
, word_length
);
601 /*DEBUG("write_blk returned %d\n", status); */
603 status
= write_blk_fifo(ft1000dev
, s_file
, c_file
, word_length
);
604 if (ft1000dev
->usbboot
== 0)
605 ft1000dev
->usbboot
++;
606 if (ft1000dev
->usbboot
== 1)
607 status
|= ft1000_write_dpram16(ft1000dev
,
608 DWNLD_MAG1_PS_HDR_LOC
, 0, 0);
613 /* Scramble downloader for Harley based ASIC via USB interface */
614 int scram_dnldr(struct ft1000_usb
*ft1000dev
, void *pFileStart
,
620 struct pseudo_hdr
*pseudo_header
;
621 u16 pseudo_header_len
;
626 struct dsp_file_hdr
*file_hdr
;
627 struct dsp_image_info
*dsp_img_info
= NULL
;
628 long requested_version
;
629 bool correct_version
;
630 struct drv_msg
*mailbox_data
;
634 u8
*boot_end
= NULL
, *code_end
= NULL
;
636 long loader_code_address
, loader_code_size
= 0;
637 long run_address
= 0, run_size
= 0;
640 u32 image_chksum
= 0;
644 struct prov_record
*pprov_record
;
645 struct ft1000_info
*pft1000info
= netdev_priv(ft1000dev
->net
);
647 DEBUG("Entered scram_dnldr...\n");
649 ft1000dev
->fcodeldr
= 0;
650 ft1000dev
->usbboot
= 0;
651 ft1000dev
->dspalive
= 0xffff;
654 * Get version id of file, at first 4 bytes of file, for newer files.
657 state
= STATE_START_DWNLD
;
659 file_hdr
= (struct dsp_file_hdr
*)pFileStart
;
661 ft1000_write_register(ft1000dev
, 0x800, FT1000_REG_MAG_WATERMARK
);
663 s_file
= (u16
*) (pFileStart
+ file_hdr
->loader_offset
);
664 c_file
= (u8
*) (pFileStart
+ file_hdr
->loader_offset
);
666 boot_end
= (u8
*) (pFileStart
+ file_hdr
->loader_code_end
);
668 loader_code_address
= file_hdr
->loader_code_address
;
669 loader_code_size
= file_hdr
->loader_code_size
;
670 correct_version
= false;
672 while ((status
== 0) && (state
!= STATE_DONE_FILE
)) {
674 case STATE_START_DWNLD
:
675 status
= scram_start_dwnld(ft1000dev
, &handshake
,
679 case STATE_BOOT_DWNLD
:
680 DEBUG("FT1000:STATE_BOOT_DWNLD\n");
681 ft1000dev
->bootmode
= 1;
682 handshake
= get_handshake(ft1000dev
, HANDSHAKE_REQUEST
);
683 if (handshake
== HANDSHAKE_REQUEST
) {
685 * Get type associated with the request.
687 request
= get_request_type(ft1000dev
);
689 case REQUEST_RUN_ADDRESS
:
690 DEBUG("FT1000:REQUEST_RUN_ADDRESS\n");
691 put_request_value(ft1000dev
,
692 loader_code_address
);
694 case REQUEST_CODE_LENGTH
:
695 DEBUG("FT1000:REQUEST_CODE_LENGTH\n");
696 put_request_value(ft1000dev
,
699 case REQUEST_DONE_BL
:
700 DEBUG("FT1000:REQUEST_DONE_BL\n");
701 /* Reposition ptrs to beginning of code section */
702 s_file
= (u16
*) (boot_end
);
703 c_file
= (u8
*) (boot_end
);
704 /* DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); */
705 /* DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); */
706 state
= STATE_CODE_DWNLD
;
707 ft1000dev
->fcodeldr
= 1;
709 case REQUEST_CODE_SEGMENT
:
710 status
= request_code_segment(ft1000dev
,
712 (const u8
*)boot_end
,
717 ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",
722 if (ft1000dev
->usbboot
)
723 put_handshake_usb(ft1000dev
,
726 put_handshake(ft1000dev
,
730 ("FT1000:download:Download error: Handshake failed\n");
736 case STATE_CODE_DWNLD
:
737 /* DEBUG("FT1000:STATE_CODE_DWNLD\n"); */
738 ft1000dev
->bootmode
= 0;
739 if (ft1000dev
->usbboot
)
741 get_handshake_usb(ft1000dev
,
745 get_handshake(ft1000dev
, HANDSHAKE_REQUEST
);
746 if (handshake
== HANDSHAKE_REQUEST
) {
748 * Get type associated with the request.
750 if (ft1000dev
->usbboot
)
752 get_request_type_usb(ft1000dev
);
754 request
= get_request_type(ft1000dev
);
756 case REQUEST_FILE_CHECKSUM
:
758 ("FT1000:download:image_chksum = 0x%8x\n",
760 put_request_value(ft1000dev
,
763 case REQUEST_RUN_ADDRESS
:
765 ("FT1000:download: REQUEST_RUN_ADDRESS\n");
766 if (correct_version
) {
768 ("FT1000:download:run_address = 0x%8x\n",
770 put_request_value(ft1000dev
,
774 ("FT1000:download:Download error: Got Run address request before image offset request.\n");
779 case REQUEST_CODE_LENGTH
:
781 ("FT1000:download:REQUEST_CODE_LENGTH\n");
782 if (correct_version
) {
784 ("FT1000:download:run_size = 0x%8x\n",
786 put_request_value(ft1000dev
,
790 ("FT1000:download:Download error: Got Size request before image offset request.\n");
795 case REQUEST_DONE_CL
:
796 ft1000dev
->usbboot
= 3;
797 /* Reposition ptrs to beginning of provisioning section */
799 (u16
*) (pFileStart
+
800 file_hdr
->commands_offset
);
803 file_hdr
->commands_offset
);
804 state
= STATE_DONE_DWNLD
;
806 case REQUEST_CODE_SEGMENT
:
807 /* DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); */
808 if (!correct_version
) {
810 ("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
815 status
= request_code_segment(ft1000dev
,
817 (const u8
*)code_end
,
822 case REQUEST_MAILBOX_DATA
:
824 ("FT1000:download: REQUEST_MAILBOX_DATA\n");
825 /* Convert length from byte count to word count. Make sure we round up. */
827 (long)(pft1000info
->DSPInfoBlklen
+
829 put_request_value(ft1000dev
,
832 (struct drv_msg
*)&(pft1000info
->
835 * Position ASIC DPRAM auto-increment pointer.
838 data
= (u16
*) &mailbox_data
->data
[0];
839 dpram
= (u16
) DWNLD_MAG1_PS_HDR_LOC
;
840 if (word_length
& 0x1)
843 word_length
= (word_length
/ 2);
845 for (; word_length
> 0; word_length
--) { /* In words */
848 templong
|= (*data
++ << 16);
850 fix_ft1000_write_dpram32
857 case REQUEST_VERSION_INFO
:
859 ("FT1000:download:REQUEST_VERSION_INFO\n");
861 file_hdr
->version_data_size
;
862 put_request_value(ft1000dev
,
865 * Position ASIC DPRAM auto-increment pointer.
869 (u16
*) (pFileStart
+
871 version_data_offset
);
873 dpram
= (u16
) DWNLD_MAG1_PS_HDR_LOC
;
874 if (word_length
& 0x1)
877 word_length
= (word_length
/ 2);
879 for (; word_length
> 0; word_length
--) { /* In words */
881 templong
= ntohs(*s_file
++);
882 temp
= ntohs(*s_file
++);
883 templong
|= (temp
<< 16);
885 fix_ft1000_write_dpram32
892 case REQUEST_CODE_BY_VERSION
:
894 ("FT1000:download:REQUEST_CODE_BY_VERSION\n");
895 correct_version
= false;
897 get_request_value(ft1000dev
);
900 (struct dsp_image_info
*)(pFileStart
907 image
< file_hdr
->nDspImages
;
910 if (dsp_img_info
->version
==
912 correct_version
= true;
914 ("FT1000:download: correct_version is TRUE\n");
943 if (!correct_version
) {
945 * Error, beyond boot code range.
948 ("FT1000:download:Download error: Bad Version Request = 0x%x.\n",
949 (int)requested_version
);
957 ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",
962 if (ft1000dev
->usbboot
)
963 put_handshake_usb(ft1000dev
,
966 put_handshake(ft1000dev
,
970 ("FT1000:download:Download error: Handshake failed\n");
976 case STATE_DONE_DWNLD
:
977 DEBUG("FT1000:download:Code loader is done...\n");
978 state
= STATE_SECTION_PROV
;
981 case STATE_SECTION_PROV
:
982 DEBUG("FT1000:download:STATE_SECTION_PROV\n");
983 pseudo_header
= (struct pseudo_hdr
*)c_file
;
985 if (pseudo_header
->checksum
==
986 hdr_checksum(pseudo_header
)) {
987 if (pseudo_header
->portdest
!=
988 0x80 /* Dsp OAM */) {
989 state
= STATE_DONE_PROV
;
992 pseudo_header_len
= ntohs(pseudo_header
->length
); /* Byte length for PROV records */
994 /* Get buffer for provisioning data */
996 kmalloc((pseudo_header_len
+
997 sizeof(struct pseudo_hdr
)),
1000 memcpy(pbuffer
, (void *)c_file
,
1001 (u32
) (pseudo_header_len
+
1004 /* link provisioning data */
1006 kmalloc(sizeof(struct prov_record
),
1009 pprov_record
->pprov_data
=
1011 list_add_tail(&pprov_record
->
1015 /* Move to next entry if available */
1017 (u8
*) ((unsigned long)
1019 (u32
) ((pseudo_header_len
+ 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr
));
1020 if ((unsigned long)(c_file
) -
1021 (unsigned long)(pFileStart
)
1023 (unsigned long)FileLength
) {
1024 state
= STATE_DONE_FILE
;
1034 /* Checksum did not compute */
1038 ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n",
1042 case STATE_DONE_PROV
:
1043 DEBUG("FT1000:download:STATE_DONE_PROV\n");
1044 state
= STATE_DONE_FILE
;
1056 // Check if Card is present
1057 status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
1058 if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
1062 status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
1063 if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
1070 DEBUG("Download exiting with status = 0x%8x\n", status
);
1071 ft1000_write_register(ft1000dev
, FT1000_DB_DNLD_TX
,
1072 FT1000_REG_DOORBELL
);