1 //=====================================================
2 // CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
5 // This file is part of Express Card USB Driver
8 //====================================================
9 // 20090926; aelias; removed compiler warnings; ubuntu 9.04; 2.6.28-15-generic
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/netdevice.h>
15 #include <linux/etherdevice.h>
16 #include <linux/usb.h>
17 #include <linux/vmalloc.h>
18 #include "ft1000_usb.h"
21 #define DWNLD_HANDSHAKE_LOC 0x02
22 #define DWNLD_TYPE_LOC 0x04
23 #define DWNLD_SIZE_MSW_LOC 0x06
24 #define DWNLD_SIZE_LSW_LOC 0x08
25 #define DWNLD_PS_HDR_LOC 0x0A
27 #define MAX_DSP_WAIT_LOOPS 40
28 #define DSP_WAIT_SLEEP_TIME 1000 /* 1 millisecond */
29 #define DSP_WAIT_DISPATCH_LVL 50 /* 50 usec */
31 #define HANDSHAKE_TIMEOUT_VALUE 0xF1F1
32 #define HANDSHAKE_RESET_VALUE 0xFEFE /* When DSP requests startover */
33 #define HANDSHAKE_RESET_VALUE_USB 0xFE7E /* When DSP requests startover */
34 #define HANDSHAKE_DSP_BL_READY 0xFEFE /* At start DSP writes this when bootloader ready */
35 #define HANDSHAKE_DSP_BL_READY_USB 0xFE7E /* At start DSP writes this when bootloader ready */
36 #define HANDSHAKE_DRIVER_READY 0xFFFF /* Driver writes after receiving 0xFEFE */
37 #define HANDSHAKE_SEND_DATA 0x0000 /* DSP writes this when ready for more data */
39 #define HANDSHAKE_REQUEST 0x0001 /* Request from DSP */
40 #define HANDSHAKE_RESPONSE 0x0000 /* Satisfied DSP request */
42 #define REQUEST_CODE_LENGTH 0x0000
43 #define REQUEST_RUN_ADDRESS 0x0001
44 #define REQUEST_CODE_SEGMENT 0x0002 /* In WORD count */
45 #define REQUEST_DONE_BL 0x0003
46 #define REQUEST_DONE_CL 0x0004
47 #define REQUEST_VERSION_INFO 0x0005
48 #define REQUEST_CODE_BY_VERSION 0x0006
49 #define REQUEST_MAILBOX_DATA 0x0007
50 #define REQUEST_FILE_CHECKSUM 0x0008
52 #define STATE_START_DWNLD 0x01
53 #define STATE_BOOT_DWNLD 0x02
54 #define STATE_CODE_DWNLD 0x03
55 #define STATE_DONE_DWNLD 0x04
56 #define STATE_SECTION_PROV 0x05
57 #define STATE_DONE_PROV 0x06
58 #define STATE_DONE_FILE 0x07
60 #define MAX_LENGTH 0x7f0
62 // Temporary download mechanism for Magnemite
63 #define DWNLD_MAG_TYPE_LOC 0x00
64 #define DWNLD_MAG_LEN_LOC 0x01
65 #define DWNLD_MAG_ADDR_LOC 0x02
66 #define DWNLD_MAG_CHKSUM_LOC 0x03
67 #define DWNLD_MAG_VAL_LOC 0x04
69 #define HANDSHAKE_MAG_DSP_BL_READY 0xFEFE0000 /* At start DSP writes this when bootloader ready */
70 #define HANDSHAKE_MAG_DSP_ENTRY 0x01000000 /* Dsp writes this to request for entry address */
71 #define HANDSHAKE_MAG_DSP_DATA 0x02000000 /* Dsp writes this to request for data block */
72 #define HANDSHAKE_MAG_DSP_DONE 0x03000000 /* Dsp writes this to indicate download done */
74 #define HANDSHAKE_MAG_DRV_READY 0xFFFF0000 /* Driver writes this to indicate ready to download */
75 #define HANDSHAKE_MAG_DRV_DATA 0x02FECDAB /* Driver writes this to indicate data available to DSP */
76 #define HANDSHAKE_MAG_DRV_ENTRY 0x01FECDAB /* Driver writes this to indicate entry point to DSP */
78 #define HANDSHAKE_MAG_TIMEOUT_VALUE 0xF1F1
81 // New Magnemite downloader
82 #define DWNLD_MAG1_HANDSHAKE_LOC 0x00
83 #define DWNLD_MAG1_TYPE_LOC 0x01
84 #define DWNLD_MAG1_SIZE_LOC 0x02
85 #define DWNLD_MAG1_PS_HDR_LOC 0x03
88 long version_id
; // Version ID of this image format.
89 long package_id
; // Package ID of code release.
90 long build_date
; // Date/time stamp when file was built.
91 long commands_offset
; // Offset to attached commands in Pseudo Hdr format.
92 long loader_offset
; // Offset to bootloader code.
93 long loader_code_address
; // Start address of bootloader.
94 long loader_code_end
; // Where bootloader code ends.
95 long loader_code_size
;
96 long version_data_offset
; // Offset were scrambled version data begins.
97 long version_data_size
; // Size, in words, of scrambled version data.
98 long nDspImages
; // Number of DSP images in file.
102 struct dsp_image_info
{
103 long coff_date
; // Date/time when DSP Coff image was built.
104 long begin_offset
; // Offset in file where image begins.
105 long end_offset
; // Offset in file where image begins.
106 long run_address
; // On chip Start address of DSP code.
107 long image_size
; // Size of image.
108 long version
; // Embedded version # of DSP code.
109 unsigned short checksum
; // DSP File checksum
114 //---------------------------------------------------------------------------
115 // Function: check_usb_db
117 // Parameters: struct ft1000_device - device structure
119 // Returns: 0 - success
121 // Description: This function checks if the doorbell register is cleared
125 //---------------------------------------------------------------------------
126 static u32
check_usb_db (struct ft1000_device
*ft1000dev
)
134 while (loopcnt
< 10) {
135 status
= ft1000_read_register(ft1000dev
, &temp
,
136 FT1000_REG_DOORBELL
);
137 DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n",
140 DEBUG("FT1000:Got checkusb doorbell\n");
141 status
= ft1000_write_register(ft1000dev
, 0x0080,
142 FT1000_REG_DOORBELL
);
143 status
= ft1000_write_register(ft1000dev
, 0x0100,
144 FT1000_REG_DOORBELL
);
145 status
= ft1000_write_register(ft1000dev
, 0x8000,
146 FT1000_REG_DOORBELL
);
156 while (loopcnt
< 20) {
157 status
= ft1000_read_register(ft1000dev
, &temp
,
158 FT1000_REG_DOORBELL
);
159 DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp
);
164 DEBUG("check_usb_db: door bell is cleared, return 0\n");
169 return HANDSHAKE_MAG_TIMEOUT_VALUE
;
172 //---------------------------------------------------------------------------
173 // Function: get_handshake
175 // Parameters: struct ft1000_device - device structure
176 // u16 expected_value - the handshake value expected
178 // Returns: handshakevalue - success
179 // HANDSHAKE_TIMEOUT_VALUE - failure
181 // Description: This function gets the handshake and compare with the expected value
185 //---------------------------------------------------------------------------
186 static u16
get_handshake(struct ft1000_device
*ft1000dev
, u16 expected_value
)
191 struct ft1000_info
*pft1000info
= netdev_priv(ft1000dev
->net
);
195 while (loopcnt
< 100) {
196 /* Need to clear downloader doorbell if Hartley ASIC */
197 status
= ft1000_write_register(ft1000dev
, FT1000_DB_DNLD_RX
,
198 FT1000_REG_DOORBELL
);
199 if (pft1000info
->fcodeldr
) {
200 DEBUG(" get_handshake: fcodeldr is %d\n",
201 pft1000info
->fcodeldr
);
202 pft1000info
->fcodeldr
= 0;
203 status
= check_usb_db(ft1000dev
);
204 if (status
!= STATUS_SUCCESS
) {
205 DEBUG("get_handshake: check_usb_db failed\n");
206 status
= STATUS_FAILURE
;
209 status
= ft1000_write_register(ft1000dev
,
211 FT1000_REG_DOORBELL
);
214 status
= ft1000_read_dpram16(ft1000dev
,
215 DWNLD_MAG1_HANDSHAKE_LOC
, (u8
*)&handshake
, 1);
216 handshake
= ntohs(handshake
);
219 return HANDSHAKE_TIMEOUT_VALUE
;
221 if ((handshake
== expected_value
) ||
222 (handshake
== HANDSHAKE_RESET_VALUE_USB
)) {
230 return HANDSHAKE_TIMEOUT_VALUE
;
233 //---------------------------------------------------------------------------
234 // Function: put_handshake
236 // Parameters: struct ft1000_device - device structure
237 // u16 handshake_value - handshake to be written
241 // Description: This function write the handshake value to the handshake location
246 //---------------------------------------------------------------------------
247 static void put_handshake(struct ft1000_device
*ft1000dev
,u16 handshake_value
)
253 tempx
= (u32
)handshake_value
;
254 tempx
= ntohl(tempx
);
256 tempword
= (u16
)(tempx
& 0xffff);
257 status
= ft1000_write_dpram16(ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
,
259 tempword
= (u16
)(tempx
>> 16);
260 status
= ft1000_write_dpram16(ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
,
262 status
= ft1000_write_register(ft1000dev
, FT1000_DB_DNLD_TX
,
263 FT1000_REG_DOORBELL
);
266 static u16
get_handshake_usb(struct ft1000_device
*ft1000dev
, u16 expected_value
)
273 struct ft1000_info
*pft1000info
= netdev_priv(ft1000dev
->net
);
277 while (loopcnt
< 100) {
278 if (pft1000info
->usbboot
== 2) {
279 status
= ft1000_read_dpram32(ft1000dev
, 0,
280 (u8
*)&(pft1000info
->tempbuf
[0]), 64);
281 for (temp
= 0; temp
< 16; temp
++) {
282 DEBUG("tempbuf %d = 0x%x\n", temp
,
283 pft1000info
->tempbuf
[temp
]);
285 status
= ft1000_read_dpram16(ft1000dev
,
286 DWNLD_MAG1_HANDSHAKE_LOC
,
287 (u8
*)&handshake
, 1);
288 DEBUG("handshake from read_dpram16 = 0x%x\n",
290 if (pft1000info
->dspalive
== pft1000info
->tempbuf
[6]) {
293 handshake
= pft1000info
->tempbuf
[1];
294 pft1000info
->dspalive
=
295 pft1000info
->tempbuf
[6];
298 status
= ft1000_read_dpram16(ft1000dev
,
299 DWNLD_MAG1_HANDSHAKE_LOC
,
300 (u8
*)&handshake
, 1);
305 handshake
= ntohs(handshake
);
306 if ((handshake
== expected_value
) ||
307 (handshake
== HANDSHAKE_RESET_VALUE_USB
))
311 return HANDSHAKE_TIMEOUT_VALUE
;
314 static void put_handshake_usb(struct ft1000_device
*ft1000dev
,u16 handshake_value
)
318 for (i
=0; i
<1000; i
++);
321 //---------------------------------------------------------------------------
322 // Function: get_request_type
324 // Parameters: struct ft1000_device - device structure
326 // Returns: request type - success
328 // Description: This function returns the request type
332 //---------------------------------------------------------------------------
333 static u16
get_request_type(struct ft1000_device
*ft1000dev
)
339 struct ft1000_info
*pft1000info
= netdev_priv(ft1000dev
->net
);
341 if (pft1000info
->bootmode
== 1) {
342 status
= fix_ft1000_read_dpram32(ft1000dev
,
343 DWNLD_MAG1_TYPE_LOC
, (u8
*)&tempx
);
344 tempx
= ntohl(tempx
);
347 status
= ft1000_read_dpram16(ft1000dev
,
348 DWNLD_MAG1_TYPE_LOC
, (u8
*)&tempword
, 1);
349 tempx
|= (tempword
<< 16);
350 tempx
= ntohl(tempx
);
352 request_type
= (u16
)tempx
;
357 static u16
get_request_type_usb(struct ft1000_device
*ft1000dev
)
363 struct ft1000_info
*pft1000info
= netdev_priv(ft1000dev
->net
);
365 if (pft1000info
->bootmode
== 1) {
366 status
= fix_ft1000_read_dpram32(ft1000dev
,
367 DWNLD_MAG1_TYPE_LOC
, (u8
*)&tempx
);
368 tempx
= ntohl(tempx
);
370 if (pft1000info
->usbboot
== 2) {
371 tempx
= pft1000info
->tempbuf
[2];
372 tempword
= pft1000info
->tempbuf
[3];
375 status
= ft1000_read_dpram16(ft1000dev
,
379 tempx
|= (tempword
<< 16);
380 tempx
= ntohl(tempx
);
382 request_type
= (u16
)tempx
;
387 //---------------------------------------------------------------------------
388 // Function: get_request_value
390 // Parameters: struct ft1000_device - device structure
392 // Returns: request value - success
394 // Description: This function returns the request value
398 //---------------------------------------------------------------------------
399 static long get_request_value(struct ft1000_device
*ft1000dev
)
404 struct ft1000_info
*pft1000info
= netdev_priv(ft1000dev
->net
);
406 if (pft1000info
->bootmode
== 1) {
407 status
= fix_ft1000_read_dpram32(ft1000dev
,
408 DWNLD_MAG1_SIZE_LOC
, (u8
*)&value
);
409 value
= ntohl(value
);
411 status
= ft1000_read_dpram16(ft1000dev
,
412 DWNLD_MAG1_SIZE_LOC
, (u8
*)&tempword
, 0);
414 status
= ft1000_read_dpram16(ft1000dev
,
415 DWNLD_MAG1_SIZE_LOC
, (u8
*)&tempword
, 1);
416 value
|= (tempword
<< 16);
417 value
= ntohl(value
);
424 //---------------------------------------------------------------------------
425 // Function: put_request_value
427 // Parameters: struct ft1000_device - device structure
428 // long lvalue - value to be put into DPRAM location DWNLD_MAG1_SIZE_LOC
432 // Description: This function writes a value to DWNLD_MAG1_SIZE_LOC
436 //---------------------------------------------------------------------------
437 static void put_request_value(struct ft1000_device
*ft1000dev
, long lvalue
)
442 tempx
= ntohl(lvalue
);
443 status
= fix_ft1000_write_dpram32(ft1000dev
, DWNLD_MAG1_SIZE_LOC
,
449 //---------------------------------------------------------------------------
450 // Function: hdr_checksum
452 // Parameters: struct pseudo_hdr *pHdr - Pseudo header pointer
454 // Returns: checksum - success
456 // Description: This function returns the checksum of the pseudo header
460 //---------------------------------------------------------------------------
461 static u16
hdr_checksum(struct pseudo_hdr
*pHdr
)
463 u16
*usPtr
= (u16
*)pHdr
;
467 chksum
= ((((((usPtr
[0] ^ usPtr
[1]) ^ usPtr
[2]) ^ usPtr
[3]) ^
468 usPtr
[4]) ^ usPtr
[5]) ^ usPtr
[6]);
473 static int check_buffers(u16
*buff_w
, u16
*buff_r
, int len
, int offset
)
477 for (i
= 0; i
< len
; i
++) {
478 if (buff_w
[i
] != buff_r
[i
+ offset
])
485 //---------------------------------------------------------------------------
486 // Function: write_blk
488 // Parameters: struct ft1000_device - device structure
489 // u16 **pUsFile - DSP image file pointer in u16
490 // u8 **pUcFile - DSP image file pointer in u8
491 // long word_length - length of the buffer to be written
494 // Returns: STATUS_SUCCESS - success
495 // STATUS_FAILURE - failure
497 // Description: This function writes a block of DSP image to DPRAM
501 //---------------------------------------------------------------------------
502 static u32
write_blk (struct ft1000_device
*ft1000dev
, u16
**pUsFile
, u8
**pUcFile
, long word_length
)
504 u32 Status
= STATUS_SUCCESS
;
509 u16 resultbuffer
[64];
510 struct ft1000_info
*pft1000info
= netdev_priv(ft1000dev
->net
);
512 //DEBUG("FT1000:download:start word_length = %d\n",(int)word_length);
513 dpram
= (u16
)DWNLD_MAG1_PS_HDR_LOC
;
514 tempword
= *(*pUsFile
);
516 Status
= ft1000_write_dpram16(ft1000dev
, dpram
, tempword
, 0);
517 tempword
= *(*pUsFile
);
519 Status
= ft1000_write_dpram16(ft1000dev
, dpram
++, tempword
, 1);
521 *pUcFile
= *pUcFile
+ 4;
523 tempword
= (u16
)word_length
;
524 word_length
= (word_length
/ 16) + 1;
525 for (; word_length
> 0; word_length
--) /* In words */
533 tempbuffer
[i
++] = *(*pUsFile
);
535 tempbuffer
[i
] = *(*pUsFile
);
537 *pUcFile
= *pUcFile
+ 4;
548 //DEBUG("write_blk: loopcnt is %d\n", loopcnt);
549 //DEBUG("write_blk: bootmode = %d\n", bootmode);
550 //DEBUG("write_blk: dpram = %x\n", dpram);
551 if (pft1000info
->bootmode
== 0)
554 Status
= ft1000_write_dpram32 (ft1000dev
, dpram
, (u8
*)&tempbuffer
[0], 8);
556 Status
= ft1000_write_dpram32 (ft1000dev
, dpram
, (u8
*)&tempbuffer
[0], 64);
562 Status
= ft1000_write_dpram32 (ft1000dev
, dpram
, (u8
*)&tempbuffer
[0], 64);
563 if (Status
== STATUS_SUCCESS
)
565 // Work around for ASIC bit stuffing problem.
566 if ( (tempbuffer
[31] & 0xfe00) == 0xfe00)
568 Status
= ft1000_write_dpram32(ft1000dev
, dpram
+12, (u8
*)&tempbuffer
[24], 64);
570 // Let's check the data written
571 Status
= ft1000_read_dpram32 (ft1000dev
, dpram
, (u8
*)&resultbuffer
[0], 64);
572 if ( (tempbuffer
[31] & 0xfe00) == 0xfe00)
574 if (check_buffers(tempbuffer
, resultbuffer
, 28, 0)) {
575 DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n");
577 Status
= STATUS_FAILURE
;
580 Status
= ft1000_read_dpram32 (ft1000dev
, dpram
+12, (u8
*)&resultbuffer
[0], 64);
582 if (check_buffers(tempbuffer
, resultbuffer
, 16, 24)) {
583 DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n");
585 Status
= STATUS_FAILURE
;
592 if (check_buffers(tempbuffer
, resultbuffer
, 32, 0)) {
593 DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n");
595 Status
= STATUS_FAILURE
;
601 if (Status
== STATUS_SUCCESS
)
607 if (Status
!= STATUS_SUCCESS
)
609 DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer
[31]);
614 dpram
= dpram
+ loopcnt
;
620 static void usb_dnld_complete (struct urb
*urb
)
622 //DEBUG("****** usb_dnld_complete\n");
625 //---------------------------------------------------------------------------
626 // Function: write_blk_fifo
628 // Parameters: struct ft1000_device - device structure
629 // u16 **pUsFile - DSP image file pointer in u16
630 // u8 **pUcFile - DSP image file pointer in u8
631 // long word_length - length of the buffer to be written
634 // Returns: STATUS_SUCCESS - success
635 // STATUS_FAILURE - failure
637 // Description: This function writes a block of DSP image to DPRAM
641 //---------------------------------------------------------------------------
642 static u32
write_blk_fifo(struct ft1000_device
*ft1000dev
, u16
**pUsFile
,
643 u8
**pUcFile
, long word_length
)
645 u32 Status
= STATUS_SUCCESS
;
648 byte_length
= word_length
* 4;
650 if (byte_length
&& ((byte_length
% 64) == 0))
653 if (byte_length
< 64)
656 usb_init_urb(ft1000dev
->tx_urb
);
657 memcpy(ft1000dev
->tx_buf
, *pUcFile
, byte_length
);
658 usb_fill_bulk_urb(ft1000dev
->tx_urb
,
660 usb_sndbulkpipe(ft1000dev
->dev
,
661 ft1000dev
->bulk_out_endpointAddr
),
662 ft1000dev
->tx_buf
, byte_length
, usb_dnld_complete
,
665 usb_submit_urb(ft1000dev
->tx_urb
, GFP_ATOMIC
);
667 *pUsFile
= *pUsFile
+ (word_length
<< 1);
668 *pUcFile
= *pUcFile
+ (word_length
<< 2);
673 //---------------------------------------------------------------------------
675 // Function: scram_dnldr
677 // Synopsis: Scramble downloader for Harley based ASIC via USB interface
679 // Arguments: pFileStart - pointer to start of file
680 // FileLength - file length
682 // Returns: status - return code
683 //---------------------------------------------------------------------------
685 u16
scram_dnldr(struct ft1000_device
*ft1000dev
, void *pFileStart
,
688 u16 status
= STATUS_SUCCESS
;
691 struct pseudo_hdr
*pseudo_header
;
692 u16 pseudo_header_len
;
698 struct dsp_file_hdr
*file_hdr
;
699 struct dsp_image_info
*dsp_img_info
= NULL
;
700 long requested_version
;
701 bool correct_version
;
702 struct drv_msg
*mailbox_data
;
706 u8
*boot_end
= NULL
, *code_end
= NULL
;
708 long loader_code_address
, loader_code_size
= 0;
709 long run_address
= 0, run_size
= 0;
712 u32 image_chksum
= 0;
716 struct prov_record
*pprov_record
;
717 struct ft1000_info
*pft1000info
= netdev_priv(ft1000dev
->net
);
719 DEBUG("Entered scram_dnldr...\n");
721 pft1000info
->fcodeldr
= 0;
722 pft1000info
->usbboot
= 0;
723 pft1000info
->dspalive
= 0xffff;
726 // Get version id of file, at first 4 bytes of file, for newer files.
729 state
= STATE_START_DWNLD
;
731 file_hdr
= (struct dsp_file_hdr
*)pFileStart
;
733 ft1000_write_register(ft1000dev
, 0x800, FT1000_REG_MAG_WATERMARK
);
735 s_file
= (u16
*) (pFileStart
+ file_hdr
->loader_offset
);
736 c_file
= (u8
*) (pFileStart
+ file_hdr
->loader_offset
);
738 boot_end
= (u8
*) (pFileStart
+ file_hdr
->loader_code_end
);
740 loader_code_address
= file_hdr
->loader_code_address
;
741 loader_code_size
= file_hdr
->loader_code_size
;
742 correct_version
= FALSE
;
744 while ((status
== STATUS_SUCCESS
) && (state
!= STATE_DONE_FILE
)) {
746 case STATE_START_DWNLD
:
747 DEBUG("FT1000:STATE_START_DWNLD\n");
748 if (pft1000info
->usbboot
)
750 get_handshake_usb(ft1000dev
,
751 HANDSHAKE_DSP_BL_READY
);
754 get_handshake(ft1000dev
,
755 HANDSHAKE_DSP_BL_READY
);
757 if (handshake
== HANDSHAKE_DSP_BL_READY
) {
759 ("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
760 put_handshake(ft1000dev
,
761 HANDSHAKE_DRIVER_READY
);
764 ("FT1000:download:Download error: Handshake failed\n");
765 status
= STATUS_FAILURE
;
768 state
= STATE_BOOT_DWNLD
;
772 case STATE_BOOT_DWNLD
:
773 DEBUG("FT1000:STATE_BOOT_DWNLD\n");
774 pft1000info
->bootmode
= 1;
775 handshake
= get_handshake(ft1000dev
, HANDSHAKE_REQUEST
);
776 if (handshake
== HANDSHAKE_REQUEST
) {
778 * Get type associated with the request.
780 request
= get_request_type(ft1000dev
);
782 case REQUEST_RUN_ADDRESS
:
783 DEBUG("FT1000:REQUEST_RUN_ADDRESS\n");
784 put_request_value(ft1000dev
,
785 loader_code_address
);
787 case REQUEST_CODE_LENGTH
:
788 DEBUG("FT1000:REQUEST_CODE_LENGTH\n");
789 put_request_value(ft1000dev
,
792 case REQUEST_DONE_BL
:
793 DEBUG("FT1000:REQUEST_DONE_BL\n");
794 /* Reposition ptrs to beginning of code section */
795 s_file
= (u16
*) (boot_end
);
796 c_file
= (u8
*) (boot_end
);
797 //DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file);
798 //DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file);
799 state
= STATE_CODE_DWNLD
;
800 pft1000info
->fcodeldr
= 1;
802 case REQUEST_CODE_SEGMENT
:
803 //DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");
805 get_request_value(ft1000dev
);
806 //DEBUG("FT1000:word_length = 0x%x\n", (int)word_length);
808 if (word_length
> MAX_LENGTH
) {
810 ("FT1000:download:Download error: Max length exceeded\n");
811 status
= STATUS_FAILURE
;
814 if ((word_length
* 2 + c_file
) >
817 * Error, beyond boot code range.
820 ("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n",
822 status
= STATUS_FAILURE
;
826 * Position ASIC DPRAM auto-increment pointer.
828 dpram
= (u16
) DWNLD_MAG1_PS_HDR_LOC
;
829 if (word_length
& 0x1)
831 word_length
= word_length
/ 2;
834 write_blk(ft1000dev
, &s_file
,
835 &c_file
, word_length
);
836 //DEBUG("write_blk returned %d\n", status);
840 ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",
842 status
= STATUS_FAILURE
;
845 if (pft1000info
->usbboot
)
846 put_handshake_usb(ft1000dev
,
849 put_handshake(ft1000dev
,
853 ("FT1000:download:Download error: Handshake failed\n");
854 status
= STATUS_FAILURE
;
859 case STATE_CODE_DWNLD
:
860 //DEBUG("FT1000:STATE_CODE_DWNLD\n");
861 pft1000info
->bootmode
= 0;
862 if (pft1000info
->usbboot
)
864 get_handshake_usb(ft1000dev
,
868 get_handshake(ft1000dev
, HANDSHAKE_REQUEST
);
869 if (handshake
== HANDSHAKE_REQUEST
) {
871 * Get type associated with the request.
873 if (pft1000info
->usbboot
)
875 get_request_type_usb(ft1000dev
);
877 request
= get_request_type(ft1000dev
);
879 case REQUEST_FILE_CHECKSUM
:
881 ("FT1000:download:image_chksum = 0x%8x\n",
883 put_request_value(ft1000dev
,
886 case REQUEST_RUN_ADDRESS
:
888 ("FT1000:download: REQUEST_RUN_ADDRESS\n");
889 if (correct_version
) {
891 ("FT1000:download:run_address = 0x%8x\n",
893 put_request_value(ft1000dev
,
897 ("FT1000:download:Download error: Got Run address request before image offset request.\n");
898 status
= STATUS_FAILURE
;
902 case REQUEST_CODE_LENGTH
:
904 ("FT1000:download:REQUEST_CODE_LENGTH\n");
905 if (correct_version
) {
907 ("FT1000:download:run_size = 0x%8x\n",
909 put_request_value(ft1000dev
,
913 ("FT1000:download:Download error: Got Size request before image offset request.\n");
914 status
= STATUS_FAILURE
;
918 case REQUEST_DONE_CL
:
919 pft1000info
->usbboot
= 3;
920 /* Reposition ptrs to beginning of provisioning section */
922 (u16
*) (pFileStart
+
923 file_hdr
->commands_offset
);
926 file_hdr
->commands_offset
);
927 state
= STATE_DONE_DWNLD
;
929 case REQUEST_CODE_SEGMENT
:
930 //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n");
931 if (!correct_version
) {
933 ("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
934 status
= STATUS_FAILURE
;
939 get_request_value(ft1000dev
);
940 //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
941 if (word_length
> MAX_LENGTH
) {
943 ("FT1000:download:Download error: Max length exceeded\n");
944 status
= STATUS_FAILURE
;
947 if ((word_length
* 2 + c_file
) >
950 * Error, beyond boot code range.
953 ("FT1000:download:Download error: Requested len=%d exceeds DSP code boundary.\n",
955 status
= STATUS_FAILURE
;
959 * Position ASIC DPRAM auto-increment pointer.
961 dpram
= (u16
) DWNLD_MAG1_PS_HDR_LOC
;
962 if (word_length
& 0x1)
964 word_length
= word_length
/ 2;
966 write_blk_fifo(ft1000dev
, &s_file
,
967 &c_file
, word_length
);
968 if (pft1000info
->usbboot
== 0)
969 pft1000info
->usbboot
++;
970 if (pft1000info
->usbboot
== 1) {
972 ft1000_write_dpram16(ft1000dev
,
973 DWNLD_MAG1_PS_HDR_LOC
,
980 case REQUEST_MAILBOX_DATA
:
982 ("FT1000:download: REQUEST_MAILBOX_DATA\n");
983 // Convert length from byte count to word count. Make sure we round up.
985 (long)(pft1000info
->DSPInfoBlklen
+
987 put_request_value(ft1000dev
,
990 (struct drv_msg
*)&(pft1000info
->
993 * Position ASIC DPRAM auto-increment pointer.
996 data
= (u16
*) & mailbox_data
->data
[0];
997 dpram
= (u16
) DWNLD_MAG1_PS_HDR_LOC
;
998 if (word_length
& 0x1)
1001 word_length
= (word_length
/ 2);
1003 for (; word_length
> 0; word_length
--) { /* In words */
1006 templong
|= (*data
++ << 16);
1008 fix_ft1000_write_dpram32
1009 (ft1000dev
, dpram
++,
1015 case REQUEST_VERSION_INFO
:
1017 ("FT1000:download:REQUEST_VERSION_INFO\n");
1019 file_hdr
->version_data_size
;
1020 put_request_value(ft1000dev
,
1023 * Position ASIC DPRAM auto-increment pointer.
1027 (u16
*) (pFileStart
+
1029 version_data_offset
);
1031 dpram
= (u16
) DWNLD_MAG1_PS_HDR_LOC
;
1032 if (word_length
& 0x1)
1035 word_length
= (word_length
/ 2);
1037 for (; word_length
> 0; word_length
--) { /* In words */
1039 templong
= ntohs(*s_file
++);
1040 temp
= ntohs(*s_file
++);
1041 templong
|= (temp
<< 16);
1043 fix_ft1000_write_dpram32
1044 (ft1000dev
, dpram
++,
1050 case REQUEST_CODE_BY_VERSION
:
1052 ("FT1000:download:REQUEST_CODE_BY_VERSION\n");
1053 correct_version
= FALSE
;
1055 get_request_value(ft1000dev
);
1058 (struct dsp_image_info
*)(pFileStart
1065 image
< file_hdr
->nDspImages
;
1068 if (dsp_img_info
->version
==
1069 requested_version
) {
1070 correct_version
= TRUE
;
1072 ("FT1000:download: correct_version is TRUE\n");
1079 (u8
*) (pFileStart
+
1083 (u8
*) (pFileStart
+
1093 (u32
) dsp_img_info
->
1101 if (!correct_version
) {
1103 * Error, beyond boot code range.
1106 ("FT1000:download:Download error: Bad Version Request = 0x%x.\n",
1107 (int)requested_version
);
1108 status
= STATUS_FAILURE
;
1115 ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",
1117 status
= STATUS_FAILURE
;
1120 if (pft1000info
->usbboot
)
1121 put_handshake_usb(ft1000dev
,
1122 HANDSHAKE_RESPONSE
);
1124 put_handshake(ft1000dev
,
1125 HANDSHAKE_RESPONSE
);
1128 ("FT1000:download:Download error: Handshake failed\n");
1129 status
= STATUS_FAILURE
;
1134 case STATE_DONE_DWNLD
:
1135 DEBUG("FT1000:download:Code loader is done...\n");
1136 state
= STATE_SECTION_PROV
;
1139 case STATE_SECTION_PROV
:
1140 DEBUG("FT1000:download:STATE_SECTION_PROV\n");
1141 pseudo_header
= (struct pseudo_hdr
*)c_file
;
1143 if (pseudo_header
->checksum
==
1144 hdr_checksum(pseudo_header
)) {
1145 if (pseudo_header
->portdest
!=
1146 0x80 /* Dsp OAM */ ) {
1147 state
= STATE_DONE_PROV
;
1150 pseudo_header_len
= ntohs(pseudo_header
->length
); /* Byte length for PROV records */
1152 // Get buffer for provisioning data
1154 kmalloc((pseudo_header_len
+
1155 sizeof(struct pseudo_hdr
)),
1158 memcpy(pbuffer
, (void *)c_file
,
1159 (u32
) (pseudo_header_len
+
1162 // link provisioning data
1164 kmalloc(sizeof(struct prov_record
),
1167 pprov_record
->pprov_data
=
1169 list_add_tail(&pprov_record
->
1173 // Move to next entry if available
1175 (u8
*) ((unsigned long)
1177 (u32
) ((pseudo_header_len
+ 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr
));
1178 if ((unsigned long)(c_file
) -
1179 (unsigned long)(pFileStart
)
1181 (unsigned long)FileLength
) {
1182 state
= STATE_DONE_FILE
;
1186 status
= STATUS_FAILURE
;
1189 status
= STATUS_FAILURE
;
1192 /* Checksum did not compute */
1193 status
= STATUS_FAILURE
;
1196 ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n",
1200 case STATE_DONE_PROV
:
1201 DEBUG("FT1000:download:STATE_DONE_PROV\n");
1202 state
= STATE_DONE_FILE
;
1206 status
= STATUS_FAILURE
;
1210 if (status
!= STATUS_SUCCESS
) {
1215 // Check if Card is present
1216 status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
1217 if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
1221 status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
1222 if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
1229 DEBUG("Download exiting with status = 0x%8x\n", status
);
1230 ft1000_write_register(ft1000dev
, FT1000_DB_DNLD_TX
,
1231 FT1000_REG_DOORBELL
);