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_usb - 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_usb *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_usb - 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_usb *ft1000dev, u16 expected_value)
194 while (loopcnt < 100) {
195 /* Need to clear downloader doorbell if Hartley ASIC */
196 status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_RX,
197 FT1000_REG_DOORBELL);
198 if (ft1000dev->fcodeldr) {
199 DEBUG(" get_handshake: fcodeldr is %d\n",
200 ft1000dev->fcodeldr);
201 ft1000dev->fcodeldr = 0;
202 status = check_usb_db(ft1000dev);
203 if (status != STATUS_SUCCESS) {
204 DEBUG("get_handshake: check_usb_db failed\n");
205 status = STATUS_FAILURE;
208 status = ft1000_write_register(ft1000dev,
210 FT1000_REG_DOORBELL);
213 status = ft1000_read_dpram16(ft1000dev,
214 DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1);
215 handshake = ntohs(handshake);
218 return HANDSHAKE_TIMEOUT_VALUE;
220 if ((handshake == expected_value) ||
221 (handshake == HANDSHAKE_RESET_VALUE_USB)) {
229 return HANDSHAKE_TIMEOUT_VALUE;
232 //---------------------------------------------------------------------------
233 // Function: put_handshake
235 // Parameters: struct ft1000_usb - device structure
236 // u16 handshake_value - handshake to be written
240 // Description: This function write the handshake value to the handshake location
245 //---------------------------------------------------------------------------
246 static void put_handshake(struct ft1000_usb *ft1000dev,u16 handshake_value)
252 tempx = (u32)handshake_value;
253 tempx = ntohl(tempx);
255 tempword = (u16)(tempx & 0xffff);
256 status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC,
258 tempword = (u16)(tempx >> 16);
259 status = ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC,
261 status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX,
262 FT1000_REG_DOORBELL);
265 static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value)
275 while (loopcnt < 100) {
276 if (ft1000dev->usbboot == 2) {
277 status = ft1000_read_dpram32(ft1000dev, 0,
278 (u8 *)&(ft1000dev->tempbuf[0]), 64);
279 for (temp = 0; temp < 16; temp++) {
280 DEBUG("tempbuf %d = 0x%x\n", temp,
281 ft1000dev->tempbuf[temp]);
283 status = ft1000_read_dpram16(ft1000dev,
284 DWNLD_MAG1_HANDSHAKE_LOC,
285 (u8 *)&handshake, 1);
286 DEBUG("handshake from read_dpram16 = 0x%x\n",
288 if (ft1000dev->dspalive == ft1000dev->tempbuf[6]) {
291 handshake = ft1000dev->tempbuf[1];
292 ft1000dev->dspalive =
293 ft1000dev->tempbuf[6];
296 status = ft1000_read_dpram16(ft1000dev,
297 DWNLD_MAG1_HANDSHAKE_LOC,
298 (u8 *)&handshake, 1);
303 handshake = ntohs(handshake);
304 if ((handshake == expected_value) ||
305 (handshake == HANDSHAKE_RESET_VALUE_USB))
309 return HANDSHAKE_TIMEOUT_VALUE;
312 static void put_handshake_usb(struct ft1000_usb *ft1000dev,u16 handshake_value)
316 for (i=0; i<1000; i++);
319 //---------------------------------------------------------------------------
320 // Function: get_request_type
322 // Parameters: struct ft1000_usb - device structure
324 // Returns: request type - success
326 // Description: This function returns the request type
330 //---------------------------------------------------------------------------
331 static u16 get_request_type(struct ft1000_usb *ft1000dev)
338 if (ft1000dev->bootmode == 1) {
339 status = fix_ft1000_read_dpram32(ft1000dev,
340 DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx);
341 tempx = ntohl(tempx);
344 status = ft1000_read_dpram16(ft1000dev,
345 DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1);
346 tempx |= (tempword << 16);
347 tempx = ntohl(tempx);
349 request_type = (u16)tempx;
354 static u16 get_request_type_usb(struct ft1000_usb *ft1000dev)
361 if (ft1000dev->bootmode == 1) {
362 status = fix_ft1000_read_dpram32(ft1000dev,
363 DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx);
364 tempx = ntohl(tempx);
366 if (ft1000dev->usbboot == 2) {
367 tempx = ft1000dev->tempbuf[2];
368 tempword = ft1000dev->tempbuf[3];
371 status = ft1000_read_dpram16(ft1000dev,
375 tempx |= (tempword << 16);
376 tempx = ntohl(tempx);
378 request_type = (u16)tempx;
383 //---------------------------------------------------------------------------
384 // Function: get_request_value
386 // Parameters: struct ft1000_usb - device structure
388 // Returns: request value - success
390 // Description: This function returns the request value
394 //---------------------------------------------------------------------------
395 static long get_request_value(struct ft1000_usb *ft1000dev)
401 if (ft1000dev->bootmode == 1) {
402 status = fix_ft1000_read_dpram32(ft1000dev,
403 DWNLD_MAG1_SIZE_LOC, (u8 *)&value);
404 value = ntohl(value);
406 status = ft1000_read_dpram16(ft1000dev,
407 DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0);
409 status = ft1000_read_dpram16(ft1000dev,
410 DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1);
411 value |= (tempword << 16);
412 value = ntohl(value);
419 //---------------------------------------------------------------------------
420 // Function: put_request_value
422 // Parameters: struct ft1000_usb - device structure
423 // long lvalue - value to be put into DPRAM location DWNLD_MAG1_SIZE_LOC
427 // Description: This function writes a value to DWNLD_MAG1_SIZE_LOC
431 //---------------------------------------------------------------------------
432 static void put_request_value(struct ft1000_usb *ft1000dev, long lvalue)
437 tempx = ntohl(lvalue);
438 status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC,
444 //---------------------------------------------------------------------------
445 // Function: hdr_checksum
447 // Parameters: struct pseudo_hdr *pHdr - Pseudo header pointer
449 // Returns: checksum - success
451 // Description: This function returns the checksum of the pseudo header
455 //---------------------------------------------------------------------------
456 static u16 hdr_checksum(struct pseudo_hdr *pHdr)
458 u16 *usPtr = (u16 *)pHdr;
462 chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^
463 usPtr[4]) ^ usPtr[5]) ^ usPtr[6]);
468 static int check_buffers(u16 *buff_w, u16 *buff_r, int len, int offset)
472 for (i = 0; i < len; i++) {
473 if (buff_w[i] != buff_r[i + offset])
480 //---------------------------------------------------------------------------
481 // Function: write_blk
483 // Parameters: struct ft1000_usb - device structure
484 // u16 **pUsFile - DSP image file pointer in u16
485 // u8 **pUcFile - DSP image file pointer in u8
486 // long word_length - length of the buffer to be written
489 // Returns: STATUS_SUCCESS - success
490 // STATUS_FAILURE - failure
492 // Description: This function writes a block of DSP image to DPRAM
496 //---------------------------------------------------------------------------
497 static u32 write_blk (struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length)
499 u32 Status = STATUS_SUCCESS;
504 u16 resultbuffer[64];
506 //DEBUG("FT1000:download:start word_length = %d\n",(int)word_length);
507 dpram = (u16)DWNLD_MAG1_PS_HDR_LOC;
508 tempword = *(*pUsFile);
510 Status = ft1000_write_dpram16(ft1000dev, dpram, tempword, 0);
511 tempword = *(*pUsFile);
513 Status = ft1000_write_dpram16(ft1000dev, dpram++, tempword, 1);
515 *pUcFile = *pUcFile + 4;
517 tempword = (u16)word_length;
518 word_length = (word_length / 16) + 1;
519 for (; word_length > 0; word_length--) /* In words */
527 tempbuffer[i++] = *(*pUsFile);
529 tempbuffer[i] = *(*pUsFile);
531 *pUcFile = *pUcFile + 4;
542 //DEBUG("write_blk: loopcnt is %d\n", loopcnt);
543 //DEBUG("write_blk: bootmode = %d\n", bootmode);
544 //DEBUG("write_blk: dpram = %x\n", dpram);
545 if (ft1000dev->bootmode == 0)
548 Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 8);
550 Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 64);
556 Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 64);
557 if (Status == STATUS_SUCCESS)
559 // Work around for ASIC bit stuffing problem.
560 if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
562 Status = ft1000_write_dpram32(ft1000dev, dpram+12, (u8 *)&tempbuffer[24], 64);
564 // Let's check the data written
565 Status = ft1000_read_dpram32 (ft1000dev, dpram, (u8 *)&resultbuffer[0], 64);
566 if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
568 if (check_buffers(tempbuffer, resultbuffer, 28, 0)) {
569 DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n");
571 Status = STATUS_FAILURE;
574 Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (u8 *)&resultbuffer[0], 64);
576 if (check_buffers(tempbuffer, resultbuffer, 16, 24)) {
577 DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n");
579 Status = STATUS_FAILURE;
586 if (check_buffers(tempbuffer, resultbuffer, 32, 0)) {
587 DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n");
589 Status = STATUS_FAILURE;
595 if (Status == STATUS_SUCCESS)
601 if (Status != STATUS_SUCCESS)
603 DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]);
608 dpram = dpram + loopcnt;
614 static void usb_dnld_complete (struct urb *urb)
616 //DEBUG("****** usb_dnld_complete\n");
619 //---------------------------------------------------------------------------
620 // Function: write_blk_fifo
622 // Parameters: struct ft1000_usb - device structure
623 // u16 **pUsFile - DSP image file pointer in u16
624 // u8 **pUcFile - DSP image file pointer in u8
625 // long word_length - length of the buffer to be written
628 // Returns: STATUS_SUCCESS - success
629 // STATUS_FAILURE - failure
631 // Description: This function writes a block of DSP image to DPRAM
635 //---------------------------------------------------------------------------
636 static u32 write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile,
637 u8 **pUcFile, long word_length)
639 u32 Status = STATUS_SUCCESS;
642 byte_length = word_length * 4;
644 if (byte_length && ((byte_length % 64) == 0))
647 if (byte_length < 64)
650 usb_init_urb(ft1000dev->tx_urb);
651 memcpy(ft1000dev->tx_buf, *pUcFile, byte_length);
652 usb_fill_bulk_urb(ft1000dev->tx_urb,
654 usb_sndbulkpipe(ft1000dev->dev,
655 ft1000dev->bulk_out_endpointAddr),
656 ft1000dev->tx_buf, byte_length, usb_dnld_complete,
659 usb_submit_urb(ft1000dev->tx_urb, GFP_ATOMIC);
661 *pUsFile = *pUsFile + (word_length << 1);
662 *pUcFile = *pUcFile + (word_length << 2);
667 //---------------------------------------------------------------------------
669 // Function: scram_dnldr
671 // Synopsis: Scramble downloader for Harley based ASIC via USB interface
673 // Arguments: pFileStart - pointer to start of file
674 // FileLength - file length
676 // Returns: status - return code
677 //---------------------------------------------------------------------------
679 u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
682 u16 status = STATUS_SUCCESS;
685 struct pseudo_hdr *pseudo_header;
686 u16 pseudo_header_len;
692 struct dsp_file_hdr *file_hdr;
693 struct dsp_image_info *dsp_img_info = NULL;
694 long requested_version;
695 bool correct_version;
696 struct drv_msg *mailbox_data;
700 u8 *boot_end = NULL, *code_end = NULL;
702 long loader_code_address, loader_code_size = 0;
703 long run_address = 0, run_size = 0;
706 u32 image_chksum = 0;
710 struct prov_record *pprov_record;
711 struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
713 DEBUG("Entered scram_dnldr...\n");
715 ft1000dev->fcodeldr = 0;
716 ft1000dev->usbboot = 0;
717 ft1000dev->dspalive = 0xffff;
720 // Get version id of file, at first 4 bytes of file, for newer files.
723 state = STATE_START_DWNLD;
725 file_hdr = (struct dsp_file_hdr *)pFileStart;
727 ft1000_write_register(ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK);
729 s_file = (u16 *) (pFileStart + file_hdr->loader_offset);
730 c_file = (u8 *) (pFileStart + file_hdr->loader_offset);
732 boot_end = (u8 *) (pFileStart + file_hdr->loader_code_end);
734 loader_code_address = file_hdr->loader_code_address;
735 loader_code_size = file_hdr->loader_code_size;
736 correct_version = FALSE;
738 while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) {
740 case STATE_START_DWNLD:
741 DEBUG("FT1000:STATE_START_DWNLD\n");
742 if (ft1000dev->usbboot)
744 get_handshake_usb(ft1000dev,
745 HANDSHAKE_DSP_BL_READY);
748 get_handshake(ft1000dev,
749 HANDSHAKE_DSP_BL_READY);
751 if (handshake == HANDSHAKE_DSP_BL_READY) {
753 ("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
754 put_handshake(ft1000dev,
755 HANDSHAKE_DRIVER_READY);
758 ("FT1000:download:Download error: Handshake failed\n");
759 status = STATUS_FAILURE;
762 state = STATE_BOOT_DWNLD;
766 case STATE_BOOT_DWNLD:
767 DEBUG("FT1000:STATE_BOOT_DWNLD\n");
768 ft1000dev->bootmode = 1;
769 handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST);
770 if (handshake == HANDSHAKE_REQUEST) {
772 * Get type associated with the request.
774 request = get_request_type(ft1000dev);
776 case REQUEST_RUN_ADDRESS:
777 DEBUG("FT1000:REQUEST_RUN_ADDRESS\n");
778 put_request_value(ft1000dev,
779 loader_code_address);
781 case REQUEST_CODE_LENGTH:
782 DEBUG("FT1000:REQUEST_CODE_LENGTH\n");
783 put_request_value(ft1000dev,
786 case REQUEST_DONE_BL:
787 DEBUG("FT1000:REQUEST_DONE_BL\n");
788 /* Reposition ptrs to beginning of code section */
789 s_file = (u16 *) (boot_end);
790 c_file = (u8 *) (boot_end);
791 //DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file);
792 //DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file);
793 state = STATE_CODE_DWNLD;
794 ft1000dev->fcodeldr = 1;
796 case REQUEST_CODE_SEGMENT:
797 //DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");
799 get_request_value(ft1000dev);
800 //DEBUG("FT1000:word_length = 0x%x\n", (int)word_length);
802 if (word_length > MAX_LENGTH) {
804 ("FT1000:download:Download error: Max length exceeded\n");
805 status = STATUS_FAILURE;
808 if ((word_length * 2 + c_file) >
811 * Error, beyond boot code range.
814 ("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n",
816 status = STATUS_FAILURE;
820 * Position ASIC DPRAM auto-increment pointer.
822 dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
823 if (word_length & 0x1)
825 word_length = word_length / 2;
828 write_blk(ft1000dev, &s_file,
829 &c_file, word_length);
830 //DEBUG("write_blk returned %d\n", status);
834 ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",
836 status = STATUS_FAILURE;
839 if (ft1000dev->usbboot)
840 put_handshake_usb(ft1000dev,
843 put_handshake(ft1000dev,
847 ("FT1000:download:Download error: Handshake failed\n");
848 status = STATUS_FAILURE;
853 case STATE_CODE_DWNLD:
854 //DEBUG("FT1000:STATE_CODE_DWNLD\n");
855 ft1000dev->bootmode = 0;
856 if (ft1000dev->usbboot)
858 get_handshake_usb(ft1000dev,
862 get_handshake(ft1000dev, HANDSHAKE_REQUEST);
863 if (handshake == HANDSHAKE_REQUEST) {
865 * Get type associated with the request.
867 if (ft1000dev->usbboot)
869 get_request_type_usb(ft1000dev);
871 request = get_request_type(ft1000dev);
873 case REQUEST_FILE_CHECKSUM:
875 ("FT1000:download:image_chksum = 0x%8x\n",
877 put_request_value(ft1000dev,
880 case REQUEST_RUN_ADDRESS:
882 ("FT1000:download: REQUEST_RUN_ADDRESS\n");
883 if (correct_version) {
885 ("FT1000:download:run_address = 0x%8x\n",
887 put_request_value(ft1000dev,
891 ("FT1000:download:Download error: Got Run address request before image offset request.\n");
892 status = STATUS_FAILURE;
896 case REQUEST_CODE_LENGTH:
898 ("FT1000:download:REQUEST_CODE_LENGTH\n");
899 if (correct_version) {
901 ("FT1000:download:run_size = 0x%8x\n",
903 put_request_value(ft1000dev,
907 ("FT1000:download:Download error: Got Size request before image offset request.\n");
908 status = STATUS_FAILURE;
912 case REQUEST_DONE_CL:
913 ft1000dev->usbboot = 3;
914 /* Reposition ptrs to beginning of provisioning section */
916 (u16 *) (pFileStart +
917 file_hdr->commands_offset);
920 file_hdr->commands_offset);
921 state = STATE_DONE_DWNLD;
923 case REQUEST_CODE_SEGMENT:
924 //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n");
925 if (!correct_version) {
927 ("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
928 status = STATUS_FAILURE;
933 get_request_value(ft1000dev);
934 //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
935 if (word_length > MAX_LENGTH) {
937 ("FT1000:download:Download error: Max length exceeded\n");
938 status = STATUS_FAILURE;
941 if ((word_length * 2 + c_file) >
944 * Error, beyond boot code range.
947 ("FT1000:download:Download error: Requested len=%d exceeds DSP code boundary.\n",
949 status = STATUS_FAILURE;
953 * Position ASIC DPRAM auto-increment pointer.
955 dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
956 if (word_length & 0x1)
958 word_length = word_length / 2;
960 write_blk_fifo(ft1000dev, &s_file,
961 &c_file, word_length);
962 if (ft1000dev->usbboot == 0)
963 ft1000dev->usbboot++;
964 if (ft1000dev->usbboot == 1) {
966 ft1000_write_dpram16(ft1000dev,
967 DWNLD_MAG1_PS_HDR_LOC,
974 case REQUEST_MAILBOX_DATA:
976 ("FT1000:download: REQUEST_MAILBOX_DATA\n");
977 // Convert length from byte count to word count. Make sure we round up.
979 (long)(pft1000info->DSPInfoBlklen +
981 put_request_value(ft1000dev,
984 (struct drv_msg *)&(pft1000info->
987 * Position ASIC DPRAM auto-increment pointer.
990 data = (u16 *) & mailbox_data->data[0];
991 dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
992 if (word_length & 0x1)
995 word_length = (word_length / 2);
997 for (; word_length > 0; word_length--) { /* In words */
1000 templong |= (*data++ << 16);
1002 fix_ft1000_write_dpram32
1003 (ft1000dev, dpram++,
1009 case REQUEST_VERSION_INFO:
1011 ("FT1000:download:REQUEST_VERSION_INFO\n");
1013 file_hdr->version_data_size;
1014 put_request_value(ft1000dev,
1017 * Position ASIC DPRAM auto-increment pointer.
1021 (u16 *) (pFileStart +
1023 version_data_offset);
1025 dpram = (u16) DWNLD_MAG1_PS_HDR_LOC;
1026 if (word_length & 0x1)
1029 word_length = (word_length / 2);
1031 for (; word_length > 0; word_length--) { /* In words */
1033 templong = ntohs(*s_file++);
1034 temp = ntohs(*s_file++);
1035 templong |= (temp << 16);
1037 fix_ft1000_write_dpram32
1038 (ft1000dev, dpram++,
1044 case REQUEST_CODE_BY_VERSION:
1046 ("FT1000:download:REQUEST_CODE_BY_VERSION\n");
1047 correct_version = FALSE;
1049 get_request_value(ft1000dev);
1052 (struct dsp_image_info *)(pFileStart
1059 image < file_hdr->nDspImages;
1062 if (dsp_img_info->version ==
1063 requested_version) {
1064 correct_version = TRUE;
1066 ("FT1000:download: correct_version is TRUE\n");
1073 (u8 *) (pFileStart +
1077 (u8 *) (pFileStart +
1087 (u32) dsp_img_info->
1095 if (!correct_version) {
1097 * Error, beyond boot code range.
1100 ("FT1000:download:Download error: Bad Version Request = 0x%x.\n",
1101 (int)requested_version);
1102 status = STATUS_FAILURE;
1109 ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",
1111 status = STATUS_FAILURE;
1114 if (ft1000dev->usbboot)
1115 put_handshake_usb(ft1000dev,
1116 HANDSHAKE_RESPONSE);
1118 put_handshake(ft1000dev,
1119 HANDSHAKE_RESPONSE);
1122 ("FT1000:download:Download error: Handshake failed\n");
1123 status = STATUS_FAILURE;
1128 case STATE_DONE_DWNLD:
1129 DEBUG("FT1000:download:Code loader is done...\n");
1130 state = STATE_SECTION_PROV;
1133 case STATE_SECTION_PROV:
1134 DEBUG("FT1000:download:STATE_SECTION_PROV\n");
1135 pseudo_header = (struct pseudo_hdr *)c_file;
1137 if (pseudo_header->checksum ==
1138 hdr_checksum(pseudo_header)) {
1139 if (pseudo_header->portdest !=
1140 0x80 /* Dsp OAM */ ) {
1141 state = STATE_DONE_PROV;
1144 pseudo_header_len = ntohs(pseudo_header->length); /* Byte length for PROV records */
1146 // Get buffer for provisioning data
1148 kmalloc((pseudo_header_len +
1149 sizeof(struct pseudo_hdr)),
1152 memcpy(pbuffer, (void *)c_file,
1153 (u32) (pseudo_header_len +
1156 // link provisioning data
1158 kmalloc(sizeof(struct prov_record),
1161 pprov_record->pprov_data =
1163 list_add_tail(&pprov_record->
1167 // Move to next entry if available
1169 (u8 *) ((unsigned long)
1171 (u32) ((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr));
1172 if ((unsigned long)(c_file) -
1173 (unsigned long)(pFileStart)
1175 (unsigned long)FileLength) {
1176 state = STATE_DONE_FILE;
1180 status = STATUS_FAILURE;
1183 status = STATUS_FAILURE;
1186 /* Checksum did not compute */
1187 status = STATUS_FAILURE;
1190 ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n",
1194 case STATE_DONE_PROV:
1195 DEBUG("FT1000:download:STATE_DONE_PROV\n");
1196 state = STATE_DONE_FILE;
1200 status = STATUS_FAILURE;
1204 if (status != STATUS_SUCCESS) {
1209 // Check if Card is present
1210 status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
1211 if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
1215 status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
1216 if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
1223 DEBUG("Download exiting with status = 0x%8x\n", status);
1224 ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX,
1225 FT1000_REG_DOORBELL);