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 ULONG check_usb_db (struct ft1000_device *ft1000dev)
136 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL);
137 DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n", temp);
140 DEBUG("FT1000:Got checkusb doorbell\n");
141 status = ft1000_write_register (ft1000dev, 0x0080, FT1000_REG_DOORBELL);
142 status = ft1000_write_register (ft1000dev, 0x0100, FT1000_REG_DOORBELL);
143 status = ft1000_write_register (ft1000dev, 0x8000, FT1000_REG_DOORBELL);
159 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL);
160 DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp);
168 DEBUG("check_usb_db: door bell is cleared, return 0\n");
172 // Check if Card is present
173 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_SUP_IMASK);
174 if (temp == 0x0000) {
178 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_ASIC_ID);
179 if (temp == 0xffff) {
185 return HANDSHAKE_MAG_TIMEOUT_VALUE;
189 //---------------------------------------------------------------------------
190 // Function: get_handshake
192 // Parameters: struct ft1000_device - device structure
193 // USHORT expected_value - the handshake value expected
195 // Returns: handshakevalue - success
196 // HANDSHAKE_TIMEOUT_VALUE - failure
198 // Description: This function gets the handshake and compare with the expected value
202 //---------------------------------------------------------------------------
203 static USHORT get_handshake(struct ft1000_device *ft1000dev, USHORT expected_value)
208 struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
211 while (loopcnt < 100)
214 // Need to clear downloader doorbell if Hartley ASIC
215 status = ft1000_write_register (ft1000dev, FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL);
216 //DEBUG("FT1000:get_handshake:doorbell = 0x%x\n", temp);
217 if (pft1000info->fcodeldr)
219 DEBUG(" get_handshake: fcodeldr is %d\n", pft1000info->fcodeldr);
220 pft1000info->fcodeldr = 0;
221 status = check_usb_db(ft1000dev);
222 if (status != STATUS_SUCCESS)
224 DEBUG("get_handshake: check_usb_db failed\n");
225 status = STATUS_FAILURE;
228 status = ft1000_write_register (ft1000dev, FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL);
231 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
232 //DEBUG("get_handshake: handshake is %x\n", tempx);
233 handshake = ntohs(handshake);
234 //DEBUG("get_handshake: after swap, handshake is %x\n", handshake);
237 return HANDSHAKE_TIMEOUT_VALUE;
239 //DEBUG("get_handshake: handshake= %x\n", handshake);
240 if ((handshake == expected_value) || (handshake == HANDSHAKE_RESET_VALUE_USB))
242 //DEBUG("get_handshake: return handshake %x\n", handshake);
250 //DEBUG("HANDSHKE LOOP: %d\n", loopcnt);
254 //DEBUG("get_handshake: return handshake time out\n");
255 return HANDSHAKE_TIMEOUT_VALUE;
258 //---------------------------------------------------------------------------
259 // Function: put_handshake
261 // Parameters: struct ft1000_device - device structure
262 // USHORT handshake_value - handshake to be written
266 // Description: This function write the handshake value to the handshake location
271 //---------------------------------------------------------------------------
272 static void put_handshake(struct ft1000_device *ft1000dev,USHORT handshake_value)
280 tempx = (ULONG)handshake_value;
281 tempx = ntohl(tempx);
283 tempword = (USHORT)(tempx & 0xffff);
284 status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 0);
285 tempword = (USHORT)(tempx >> 16);
286 status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 1);
287 status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL);
290 static USHORT get_handshake_usb(struct ft1000_device *ft1000dev, USHORT expected_value)
297 struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
300 while (loopcnt < 100)
302 if (pft1000info->usbboot == 2) {
303 status = ft1000_read_dpram32 (ft1000dev, 0, (PUCHAR)&(pft1000info->tempbuf[0]), 64);
304 for (temp=0; temp<16; temp++)
305 DEBUG("tempbuf %d = 0x%x\n", temp, pft1000info->tempbuf[temp]);
306 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
307 DEBUG("handshake from read_dpram16 = 0x%x\n", handshake);
308 if (pft1000info->dspalive == pft1000info->tempbuf[6])
311 handshake = pft1000info->tempbuf[1];
312 pft1000info->dspalive = pft1000info->tempbuf[6];
316 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
320 handshake = ntohs(handshake);
321 if ((handshake == expected_value) || (handshake == HANDSHAKE_RESET_VALUE_USB))
327 return HANDSHAKE_TIMEOUT_VALUE;
330 static void put_handshake_usb(struct ft1000_device *ft1000dev,USHORT handshake_value)
334 for (i=0; i<1000; i++);
337 //---------------------------------------------------------------------------
338 // Function: get_request_type
340 // Parameters: struct ft1000_device - device structure
342 // Returns: request type - success
344 // Description: This function returns the request type
348 //---------------------------------------------------------------------------
349 static USHORT get_request_type(struct ft1000_device *ft1000dev)
355 struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
357 if ( pft1000info->bootmode == 1)
359 status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempx);
360 tempx = ntohl(tempx);
366 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 1);
367 tempx |= (tempword << 16);
368 tempx = ntohl(tempx);
370 request_type = (USHORT)tempx;
372 //DEBUG("get_request_type: request_type is %x\n", request_type);
377 static USHORT get_request_type_usb(struct ft1000_device *ft1000dev)
383 struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
384 if ( pft1000info->bootmode == 1)
386 status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempx);
387 tempx = ntohl(tempx);
391 if (pft1000info->usbboot == 2) {
392 tempx = pft1000info->tempbuf[2];
393 tempword = pft1000info->tempbuf[3];
397 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 1);
399 tempx |= (tempword << 16);
400 tempx = ntohl(tempx);
402 request_type = (USHORT)tempx;
404 //DEBUG("get_request_type: request_type is %x\n", request_type);
409 //---------------------------------------------------------------------------
410 // Function: get_request_value
412 // Parameters: struct ft1000_device - device structure
414 // Returns: request value - success
416 // Description: This function returns the request value
420 //---------------------------------------------------------------------------
421 static long get_request_value(struct ft1000_device *ft1000dev)
426 struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
429 if ( pft1000info->bootmode == 1)
431 status = fix_ft1000_read_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&value);
432 value = ntohl(value);
436 status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 0);
438 status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 1);
439 value |= (tempword << 16);
440 value = ntohl(value);
444 //DEBUG("get_request_value: value is %x\n", value);
450 static long get_request_value_usb(struct ft1000_device *ft1000dev)
455 struct ft1000_info * pft1000info = netdev_priv(ft1000dev->net);
457 if (pft1000info->usbboot == 2) {
458 value = pft1000info->tempbuf[4];
459 tempword = pft1000info->tempbuf[5];
463 status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 1);
466 value |= (tempword << 16);
467 value = ntohl(value);
469 if (pft1000info->usbboot == 1)
470 pft1000info->usbboot = 2;
472 //DEBUG("get_request_value_usb: value is %x\n", value);
478 //---------------------------------------------------------------------------
479 // Function: put_request_value
481 // Parameters: struct ft1000_device - device structure
482 // long lvalue - value to be put into DPRAM location DWNLD_MAG1_SIZE_LOC
486 // Description: This function writes a value to DWNLD_MAG1_SIZE_LOC
490 //---------------------------------------------------------------------------
491 static void put_request_value(struct ft1000_device *ft1000dev, long lvalue)
496 tempx = ntohl(lvalue);
497 status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempx);
501 //DEBUG("put_request_value: value is %x\n", lvalue);
507 //---------------------------------------------------------------------------
508 // Function: hdr_checksum
510 // Parameters: struct pseudo_hdr *pHdr - Pseudo header pointer
512 // Returns: checksum - success
514 // Description: This function returns the checksum of the pseudo header
518 //---------------------------------------------------------------------------
519 static USHORT hdr_checksum(struct pseudo_hdr *pHdr)
521 USHORT *usPtr = (USHORT *)pHdr;
525 chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^
526 usPtr[4]) ^ usPtr[5]) ^ usPtr[6]);
532 //---------------------------------------------------------------------------
533 // Function: write_blk
535 // Parameters: struct ft1000_device - device structure
536 // USHORT **pUsFile - DSP image file pointer in USHORT
537 // UCHAR **pUcFile - DSP image file pointer in UCHAR
538 // long word_length - lenght of the buffer to be written
541 // Returns: STATUS_SUCCESS - success
542 // STATUS_FAILURE - failure
544 // Description: This function writes a block of DSP image to DPRAM
548 //---------------------------------------------------------------------------
549 static ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length)
551 ULONG Status = STATUS_SUCCESS;
553 long temp_word_length;
557 USHORT tempbuffer[64];
558 USHORT resultbuffer[64];
559 struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
561 //DEBUG("FT1000:download:start word_length = %d\n",(int)word_length);
562 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
563 tempword = *(*pUsFile);
565 Status = ft1000_write_dpram16(ft1000dev, dpram, tempword, 0);
566 tempword = *(*pUsFile);
568 Status = ft1000_write_dpram16(ft1000dev, dpram++, tempword, 1);
570 *pUcFile = *pUcFile + 4;
572 tempword = (USHORT)word_length;
573 word_length = (word_length / 16) + 1;
574 pTempFile = *pUsFile;
575 temp_word_length = word_length;
576 for (; word_length > 0; word_length--) /* In words */
584 tempbuffer[i++] = *(*pUsFile);
586 tempbuffer[i] = *(*pUsFile);
588 *pUcFile = *pUcFile + 4;
599 //DEBUG("write_blk: loopcnt is %d\n", loopcnt);
600 //DEBUG("write_blk: bootmode = %d\n", bootmode);
601 //DEBUG("write_blk: dpram = %x\n", dpram);
602 if (pft1000info->bootmode == 0)
605 Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 8);
607 Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 64);
613 Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 64);
614 if (Status == STATUS_SUCCESS)
616 // Work around for ASIC bit stuffing problem.
617 if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
619 Status = ft1000_write_dpram32(ft1000dev, dpram+12, (PUCHAR)&tempbuffer[24], 64);
621 // Let's check the data written
622 Status = ft1000_read_dpram32 (ft1000dev, dpram, (PUCHAR)&resultbuffer[0], 64);
623 if ( (tempbuffer[31] & 0xfe00) == 0xfe00)
627 if (resultbuffer[i] != tempbuffer[i])
630 DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n");
632 Status = STATUS_FAILURE;
636 Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (PUCHAR)&resultbuffer[0], 64);
639 if (resultbuffer[i] != tempbuffer[i+24])
642 DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n");
644 Status = STATUS_FAILURE;
653 if (resultbuffer[i] != tempbuffer[i])
656 DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n");
658 Status = STATUS_FAILURE;
664 if (Status == STATUS_SUCCESS)
670 if (Status != STATUS_SUCCESS)
672 DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]);
677 dpram = dpram + loopcnt;
683 static void usb_dnld_complete (struct urb *urb)
685 //DEBUG("****** usb_dnld_complete\n");
688 //---------------------------------------------------------------------------
689 // Function: write_blk_fifo
691 // Parameters: struct ft1000_device - device structure
692 // USHORT **pUsFile - DSP image file pointer in USHORT
693 // UCHAR **pUcFile - DSP image file pointer in UCHAR
694 // long word_length - lenght of the buffer to be written
697 // Returns: STATUS_SUCCESS - success
698 // STATUS_FAILURE - failure
700 // Description: This function writes a block of DSP image to DPRAM
704 //---------------------------------------------------------------------------
705 static ULONG write_blk_fifo (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length)
707 ULONG Status = STATUS_SUCCESS;
711 byte_length = word_length * 4;
714 aligncnt = 4 - (byte_length % 4);
717 byte_length += aligncnt;
719 if (byte_length && ((byte_length % 64) == 0)) {
723 if (byte_length < 64)
727 pblk = kzalloc(byte_length, GFP_KERNEL);
728 memcpy (pblk, *pUcFile, byte_length);
730 pipe = usb_sndbulkpipe (ft1000dev->dev, ft1000dev->bulk_out_endpointAddr);
732 Status = usb_bulk_msg (ft1000dev->dev,
738 DEBUG("write_blk_fifo Status = 0x%8x Bytes Transfer = %d Data = 0x%x\n", Status, cnt, *pblk);
742 usb_init_urb(ft1000dev->tx_urb);
743 memcpy (ft1000dev->tx_buf, *pUcFile, byte_length);
744 usb_fill_bulk_urb(ft1000dev->tx_urb,
746 usb_sndbulkpipe(ft1000dev->dev, ft1000dev->bulk_out_endpointAddr),
752 usb_submit_urb(ft1000dev->tx_urb, GFP_ATOMIC);
755 *pUsFile = *pUsFile + (word_length << 1);
756 *pUcFile = *pUcFile + (word_length << 2);
761 //---------------------------------------------------------------------------
763 // Function: scram_dnldr
765 // Synopsis: Scramble downloader for Harley based ASIC via USB interface
767 // Arguments: pFileStart - pointer to start of file
768 // FileLength - file length
770 // Returns: status - return code
771 //---------------------------------------------------------------------------
773 u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLength)
775 u16 Status = STATUS_SUCCESS;
778 struct pseudo_hdr *pHdr;
785 struct dsp_file_hdr *pFileHdr5;
786 struct dsp_image_info *pDspImageInfoV6 = NULL;
787 long requested_version;
788 BOOLEAN bGoodVersion;
789 struct drv_msg *pMailBoxData;
790 USHORT *pUsData = NULL;
791 USHORT *pUsFile = NULL;
792 UCHAR *pUcFile = NULL;
793 UCHAR *pBootEnd = NULL, *pCodeEnd= NULL;
795 long loader_code_address, loader_code_size = 0;
796 long run_address = 0, run_size = 0;
799 ULONG image_chksum = 0;
803 struct prov_record *pprov_record;
804 struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net);
806 DEBUG("Entered scram_dnldr...\n");
808 pft1000info->fcodeldr = 0;
809 pft1000info->usbboot = 0;
810 pft1000info->dspalive = 0xffff;
814 // Get version id of file, at first 4 bytes of file, for newer files.
817 uiState = STATE_START_DWNLD;
819 pFileHdr5 = (struct dsp_file_hdr *)pFileStart;
821 ft1000_write_register (ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK);
823 pUsFile = (USHORT *)(pFileStart + pFileHdr5->loader_offset);
824 pUcFile = (UCHAR *)(pFileStart + pFileHdr5->loader_offset);
826 pBootEnd = (UCHAR *)(pFileStart + pFileHdr5->loader_code_end);
828 loader_code_address = pFileHdr5->loader_code_address;
829 loader_code_size = pFileHdr5->loader_code_size;
830 bGoodVersion = FALSE;
832 while ((Status == STATUS_SUCCESS) && (uiState != STATE_DONE_FILE))
836 case STATE_START_DWNLD:
837 DEBUG("FT1000:STATE_START_DWNLD\n");
838 if (pft1000info->usbboot)
839 handshake = get_handshake_usb(ft1000dev, HANDSHAKE_DSP_BL_READY);
841 handshake = get_handshake(ft1000dev, HANDSHAKE_DSP_BL_READY);
843 if (handshake == HANDSHAKE_DSP_BL_READY)
845 DEBUG("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
846 put_handshake(ft1000dev, HANDSHAKE_DRIVER_READY);
850 DEBUG("FT1000:download:Download error: Handshake failed\n");
851 Status = STATUS_FAILURE;
854 uiState = STATE_BOOT_DWNLD;
858 case STATE_BOOT_DWNLD:
859 DEBUG("FT1000:STATE_BOOT_DWNLD\n");
860 pft1000info->bootmode = 1;
861 handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST);
862 if (handshake == HANDSHAKE_REQUEST)
865 * Get type associated with the request.
867 request = get_request_type(ft1000dev);
870 case REQUEST_RUN_ADDRESS:
871 DEBUG("FT1000:REQUEST_RUN_ADDRESS\n");
872 put_request_value(ft1000dev, loader_code_address);
874 case REQUEST_CODE_LENGTH:
875 DEBUG("FT1000:REQUEST_CODE_LENGTH\n");
876 put_request_value(ft1000dev, loader_code_size);
878 case REQUEST_DONE_BL:
879 DEBUG("FT1000:REQUEST_DONE_BL\n");
880 /* Reposition ptrs to beginning of code section */
881 pUsFile = (USHORT *)(pBootEnd);
882 pUcFile = (UCHAR *)(pBootEnd);
883 //DEBUG("FT1000:download:pUsFile = 0x%8x\n", (int)pUsFile);
884 //DEBUG("FT1000:download:pUcFile = 0x%8x\n", (int)pUcFile);
885 uiState = STATE_CODE_DWNLD;
886 pft1000info->fcodeldr = 1;
888 case REQUEST_CODE_SEGMENT:
889 //DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");
890 word_length = get_request_value(ft1000dev);
891 //DEBUG("FT1000:word_length = 0x%x\n", (int)word_length);
893 if (word_length > MAX_LENGTH)
895 DEBUG("FT1000:download:Download error: Max length exceeded\n");
896 Status = STATUS_FAILURE;
899 if ( (word_length*2 + pUcFile) > pBootEnd)
902 * Error, beyond boot code range.
904 DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundry.\n",
906 Status = STATUS_FAILURE;
910 * Position ASIC DPRAM auto-increment pointer.
912 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
913 if (word_length & 0x1)
915 word_length = word_length / 2;
917 Status = write_blk(ft1000dev, &pUsFile, &pUcFile, word_length);
918 //DEBUG("write_blk returned %d\n", Status);
921 DEBUG("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",request);
922 Status = STATUS_FAILURE;
925 if (pft1000info->usbboot)
926 put_handshake_usb(ft1000dev, HANDSHAKE_RESPONSE);
928 put_handshake(ft1000dev, HANDSHAKE_RESPONSE);
932 DEBUG("FT1000:download:Download error: Handshake failed\n");
933 Status = STATUS_FAILURE;
938 case STATE_CODE_DWNLD:
939 //DEBUG("FT1000:STATE_CODE_DWNLD\n");
940 pft1000info->bootmode = 0;
941 if (pft1000info->usbboot)
942 handshake = get_handshake_usb(ft1000dev, HANDSHAKE_REQUEST);
944 handshake = get_handshake(ft1000dev, HANDSHAKE_REQUEST);
945 if (handshake == HANDSHAKE_REQUEST)
948 * Get type associated with the request.
950 if (pft1000info->usbboot)
951 request = get_request_type_usb(ft1000dev);
953 request = get_request_type(ft1000dev);
956 case REQUEST_FILE_CHECKSUM:
957 DEBUG("FT1000:download:image_chksum = 0x%8x\n", image_chksum);
958 put_request_value(ft1000dev, image_chksum);
960 case REQUEST_RUN_ADDRESS:
961 DEBUG("FT1000:download: REQUEST_RUN_ADDRESS\n");
964 DEBUG("FT1000:download:run_address = 0x%8x\n", (int)run_address);
965 put_request_value(ft1000dev, run_address);
969 DEBUG("FT1000:download:Download error: Got Run address request before image offset request.\n");
970 Status = STATUS_FAILURE;
974 case REQUEST_CODE_LENGTH:
975 DEBUG("FT1000:download:REQUEST_CODE_LENGTH\n");
978 DEBUG("FT1000:download:run_size = 0x%8x\n", (int)run_size);
979 put_request_value(ft1000dev, run_size);
983 DEBUG("FT1000:download:Download error: Got Size request before image offset request.\n");
984 Status = STATUS_FAILURE;
988 case REQUEST_DONE_CL:
989 pft1000info->usbboot = 3;
990 /* Reposition ptrs to beginning of provisioning section */
991 pUsFile = (USHORT *)(pFileStart + pFileHdr5->commands_offset);
992 pUcFile = (UCHAR *)(pFileStart + pFileHdr5->commands_offset);
993 uiState = STATE_DONE_DWNLD;
995 case REQUEST_CODE_SEGMENT:
996 //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n");
999 DEBUG("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
1000 Status = STATUS_FAILURE;
1004 word_length = get_request_value_usb(ft1000dev);
1005 //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
1006 if (word_length > MAX_LENGTH/2)
1008 word_length = get_request_value(ft1000dev);
1009 //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
1010 if (word_length > MAX_LENGTH)
1013 DEBUG("FT1000:download:Download error: Max length exceeded\n");
1014 Status = STATUS_FAILURE;
1017 if ( (word_length*2 + pUcFile) > pCodeEnd)
1020 * Error, beyond boot code range.
1022 DEBUG("FT1000:download:Download error: Requested len=%d exceeds DSP code boundry.\n",
1024 Status = STATUS_FAILURE;
1028 * Position ASIC DPRAM auto-increment pointer.
1030 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
1031 if (word_length & 0x1)
1033 word_length = word_length / 2;
1035 write_blk_fifo (ft1000dev, &pUsFile, &pUcFile, word_length);
1036 if (pft1000info->usbboot == 0)
1037 pft1000info->usbboot++;
1038 if (pft1000info->usbboot == 1) {
1040 ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_PS_HDR_LOC, tempword, 0);
1045 case REQUEST_MAILBOX_DATA:
1046 DEBUG("FT1000:download: REQUEST_MAILBOX_DATA\n");
1047 // Convert length from byte count to word count. Make sure we round up.
1048 word_length = (long)(pft1000info->DSPInfoBlklen + 1)/2;
1049 put_request_value(ft1000dev, word_length);
1050 pMailBoxData = (struct drv_msg *)&(pft1000info->DSPInfoBlk[0]);
1052 * Position ASIC DPRAM auto-increment pointer.
1056 pUsData = (USHORT *)&pMailBoxData->data[0];
1057 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
1058 if (word_length & 0x1)
1061 word_length = (word_length / 2);
1064 for (; word_length > 0; word_length--) /* In words */
1067 templong = *pUsData++;
1068 templong |= (*pUsData++ << 16);
1069 Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (PUCHAR)&templong);
1074 case REQUEST_VERSION_INFO:
1075 DEBUG("FT1000:download:REQUEST_VERSION_INFO\n");
1076 word_length = pFileHdr5->version_data_size;
1077 put_request_value(ft1000dev, word_length);
1079 * Position ASIC DPRAM auto-increment pointer.
1082 pUsFile = (USHORT *)(pFileStart + pFileHdr5->version_data_offset);
1085 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
1086 if (word_length & 0x1)
1089 word_length = (word_length / 2);
1092 for (; word_length > 0; word_length--) /* In words */
1095 templong = ntohs(*pUsFile++);
1096 temp = ntohs(*pUsFile++);
1097 templong |= (temp << 16);
1098 Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (PUCHAR)&templong);
1103 case REQUEST_CODE_BY_VERSION:
1104 DEBUG("FT1000:download:REQUEST_CODE_BY_VERSION\n");
1105 bGoodVersion = FALSE;
1106 requested_version = get_request_value(ft1000dev);
1108 pDspImageInfoV6 = (struct dsp_image_info *)(pFileStart + sizeof(struct dsp_file_hdr ));
1110 for (imageN = 0; imageN < pFileHdr5->nDspImages; imageN++)
1113 temp = (USHORT)(pDspImageInfoV6->version);
1115 temp = (USHORT)(pDspImageInfoV6->version >> 16);
1116 templong |= (temp << 16);
1117 if (templong == (ULONG)requested_version)
1119 bGoodVersion = TRUE;
1120 DEBUG("FT1000:download: bGoodVersion is TRUE\n");
1121 pUsFile = (USHORT *)(pFileStart + pDspImageInfoV6->begin_offset);
1122 pUcFile = (UCHAR *)(pFileStart + pDspImageInfoV6->begin_offset);
1123 pCodeEnd = (UCHAR *)(pFileStart + pDspImageInfoV6->end_offset);
1124 run_address = pDspImageInfoV6->run_address;
1125 run_size = pDspImageInfoV6->image_size;
1126 image_chksum = (ULONG)pDspImageInfoV6->checksum;
1137 * Error, beyond boot code range.
1139 DEBUG("FT1000:download:Download error: Bad Version Request = 0x%x.\n",(int)requested_version);
1140 Status = STATUS_FAILURE;
1146 DEBUG("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",request);
1147 Status = STATUS_FAILURE;
1150 if (pft1000info->usbboot)
1151 put_handshake_usb(ft1000dev, HANDSHAKE_RESPONSE);
1153 put_handshake(ft1000dev, HANDSHAKE_RESPONSE);
1157 DEBUG("FT1000:download:Download error: Handshake failed\n");
1158 Status = STATUS_FAILURE;
1163 case STATE_DONE_DWNLD:
1164 DEBUG("FT1000:download:Code loader is done...\n");
1165 uiState = STATE_SECTION_PROV;
1168 case STATE_SECTION_PROV:
1169 DEBUG("FT1000:download:STATE_SECTION_PROV\n");
1170 pHdr = (struct pseudo_hdr *)pUcFile;
1172 if (pHdr->checksum == hdr_checksum(pHdr))
1174 if (pHdr->portdest != 0x80 /* Dsp OAM */)
1176 uiState = STATE_DONE_PROV;
1179 usHdrLength = ntohs(pHdr->length); /* Byte length for PROV records */
1181 // Get buffer for provisioning data
1182 pbuffer = kmalloc((usHdrLength + sizeof(struct pseudo_hdr)), GFP_ATOMIC);
1184 memcpy(pbuffer, (void *)pUcFile, (UINT)(usHdrLength + sizeof(struct pseudo_hdr)));
1185 // link provisioning data
1186 pprov_record = kmalloc(sizeof(struct prov_record), GFP_ATOMIC);
1188 pprov_record->pprov_data = pbuffer;
1189 list_add_tail (&pprov_record->list, &pft1000info->prov_list);
1190 // Move to next entry if available
1191 pUcFile = (UCHAR *)((unsigned long)pUcFile + (UINT)((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr));
1192 if ( (unsigned long)(pUcFile) - (unsigned long)(pFileStart) >= (unsigned long)FileLength) {
1193 uiState = STATE_DONE_FILE;
1198 Status = STATUS_FAILURE;
1202 Status = STATUS_FAILURE;
1207 /* Checksum did not compute */
1208 Status = STATUS_FAILURE;
1210 DEBUG("ft1000:download: after STATE_SECTION_PROV, uiState = %d, Status= %d\n", uiState, Status);
1213 case STATE_DONE_PROV:
1214 DEBUG("FT1000:download:STATE_DONE_PROV\n");
1215 uiState = STATE_DONE_FILE;
1220 Status = STATUS_FAILURE;
1224 if (Status != STATUS_SUCCESS) {
1229 // Check if Card is present
1230 Status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
1231 if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
1235 Status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
1236 if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
1243 DEBUG("Download exiting with status = 0x%8x\n", Status);
1244 ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL);