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"
22 #define DWNLD_HANDSHAKE_LOC 0x02
23 #define DWNLD_TYPE_LOC 0x04
24 #define DWNLD_SIZE_MSW_LOC 0x06
25 #define DWNLD_SIZE_LSW_LOC 0x08
26 #define DWNLD_PS_HDR_LOC 0x0A
28 #define MAX_DSP_WAIT_LOOPS 40
29 #define DSP_WAIT_SLEEP_TIME 1000 /* 1 millisecond */
30 #define DSP_WAIT_DISPATCH_LVL 50 /* 50 usec */
32 #define HANDSHAKE_TIMEOUT_VALUE 0xF1F1
33 #define HANDSHAKE_RESET_VALUE 0xFEFE /* When DSP requests startover */
34 #define HANDSHAKE_RESET_VALUE_USB 0xFE7E /* When DSP requests startover */
35 #define HANDSHAKE_DSP_BL_READY 0xFEFE /* At start DSP writes this when bootloader ready */
36 #define HANDSHAKE_DSP_BL_READY_USB 0xFE7E /* At start DSP writes this when bootloader ready */
37 #define HANDSHAKE_DRIVER_READY 0xFFFF /* Driver writes after receiving 0xFEFE */
38 #define HANDSHAKE_SEND_DATA 0x0000 /* DSP writes this when ready for more data */
40 #define HANDSHAKE_REQUEST 0x0001 /* Request from DSP */
41 #define HANDSHAKE_RESPONSE 0x0000 /* Satisfied DSP request */
43 #define REQUEST_CODE_LENGTH 0x0000
44 #define REQUEST_RUN_ADDRESS 0x0001
45 #define REQUEST_CODE_SEGMENT 0x0002 /* In WORD count */
46 #define REQUEST_DONE_BL 0x0003
47 #define REQUEST_DONE_CL 0x0004
48 #define REQUEST_VERSION_INFO 0x0005
49 #define REQUEST_CODE_BY_VERSION 0x0006
50 #define REQUEST_MAILBOX_DATA 0x0007
51 #define REQUEST_FILE_CHECKSUM 0x0008
53 #define STATE_START_DWNLD 0x01
54 #define STATE_BOOT_DWNLD 0x02
55 #define STATE_CODE_DWNLD 0x03
56 #define STATE_DONE_DWNLD 0x04
57 #define STATE_SECTION_PROV 0x05
58 #define STATE_DONE_PROV 0x06
59 #define STATE_DONE_FILE 0x07
61 #define MAX_LENGTH 0x7f0
63 // Temporary download mechanism for Magnemite
64 #define DWNLD_MAG_TYPE_LOC 0x00
65 #define DWNLD_MAG_LEN_LOC 0x01
66 #define DWNLD_MAG_ADDR_LOC 0x02
67 #define DWNLD_MAG_CHKSUM_LOC 0x03
68 #define DWNLD_MAG_VAL_LOC 0x04
70 #define HANDSHAKE_MAG_DSP_BL_READY 0xFEFE0000 /* At start DSP writes this when bootloader ready */
71 #define HANDSHAKE_MAG_DSP_ENTRY 0x01000000 /* Dsp writes this to request for entry address */
72 #define HANDSHAKE_MAG_DSP_DATA 0x02000000 /* Dsp writes this to request for data block */
73 #define HANDSHAKE_MAG_DSP_DONE 0x03000000 /* Dsp writes this to indicate download done */
75 #define HANDSHAKE_MAG_DRV_READY 0xFFFF0000 /* Driver writes this to indicate ready to download */
76 #define HANDSHAKE_MAG_DRV_DATA 0x02FECDAB /* Driver writes this to indicate data available to DSP */
77 #define HANDSHAKE_MAG_DRV_ENTRY 0x01FECDAB /* Driver writes this to indicate entry point to DSP */
79 #define HANDSHAKE_MAG_TIMEOUT_VALUE 0xF1F1
82 // New Magnemite downloader
83 #define DWNLD_MAG1_HANDSHAKE_LOC 0x00
84 #define DWNLD_MAG1_TYPE_LOC 0x01
85 #define DWNLD_MAG1_SIZE_LOC 0x02
86 #define DWNLD_MAG1_PS_HDR_LOC 0x03
88 #pragma pack (push, pack_save, 1)
89 typedef struct _DSP_FILE_HDR
{
92 long loader_code_address
;
93 long loader_code_size
;
95 long dsp_code_address
;
99 } DSP_FILE_HDR
, *PDSP_FILE_HDR
;
101 typedef struct _DSP_FILE_HDR_5
{
102 long version_id
; // Version ID of this image format.
103 long package_id
; // Package ID of code release.
104 long build_date
; // Date/time stamp when file was built.
105 long commands_offset
; // Offset to attached commands in Pseudo Hdr format.
106 long loader_offset
; // Offset to bootloader code.
107 long loader_code_address
; // Start address of bootloader.
108 long loader_code_end
; // Where bootloader code ends.
109 long loader_code_size
;
110 long version_data_offset
; // Offset were scrambled version data begins.
111 long version_data_size
; // Size, in words, of scrambled version data.
112 long nDspImages
; // Number of DSP images in file.
113 } DSP_FILE_HDR_5
, * PDSP_FILE_HDR_5
;
115 typedef struct _DSP_IMAGE_INFO
{
116 long coff_date
; // Date/time when DSP Coff image was built.
117 long begin_offset
; // Offset in file where image begins.
118 long end_offset
; // Offset in file where image begins.
119 long run_address
; // On chip Start address of DSP code.
120 long image_size
; // Size of image.
121 long version
; // Embedded version # of DSP code.
122 } DSP_IMAGE_INFO
, *PDSP_IMAGE_INFO
;
124 typedef struct _DSP_IMAGE_INFO_V6
{
125 long coff_date
; // Date/time when DSP Coff image was built.
126 long begin_offset
; // Offset in file where image begins.
127 long end_offset
; // Offset in file where image begins.
128 long run_address
; // On chip Start address of DSP code.
129 long image_size
; // Size of image.
130 long version
; // Embedded version # of DSP code.
131 unsigned short checksum
; // DSP File checksum
133 } DSP_IMAGE_INFO_V6
, *PDSP_IMAGE_INFO_V6
;
136 u16
ft1000_read_register(struct ft1000_device
*ft1000dev
, short* Data
, u16 nRegIndx
);
137 u16
ft1000_write_register(struct ft1000_device
*ft1000dev
, USHORT value
, u16 nRegIndx
);
138 u16
ft1000_read_dpram32(struct ft1000_device
*ft1000dev
, USHORT indx
, PUCHAR buffer
, USHORT cnt
);
139 u16
ft1000_write_dpram32(struct ft1000_device
*ft1000dev
, USHORT indx
, PUCHAR buffer
, USHORT cnt
);
140 u16
ft1000_read_dpram16(struct ft1000_device
*ft1000dev
, USHORT indx
, PUCHAR buffer
, u8 highlow
);
141 u16
ft1000_write_dpram16(struct ft1000_device
*ft1000dev
, USHORT indx
, USHORT value
, u8 highlow
);
142 u16
fix_ft1000_read_dpram32(struct ft1000_device
*ft1000dev
, USHORT indx
, PUCHAR buffer
);
143 u16
fix_ft1000_write_dpram32(struct ft1000_device
*ft1000dev
, USHORT indx
, PUCHAR buffer
);
145 //---------------------------------------------------------------------------
148 // Parameters: char *fn - input DSP image file name
149 // int *pimgsz - output DSP image file size
150 // Returns: DSP image buffer
152 // Description: Read the DSP image file into a char buffer
156 //---------------------------------------------------------------------------
157 char *getfw (char *fn
, int *pimgsz
)
160 mm_segment_t fs
= get_fs();
167 fd
= filp_open(fn
, 0, 0);
170 DEBUG("FT1000:%s:can not open dsp image\n", __FUNCTION__
);
175 fwimgsz
= i_size_read(fd
->f_dentry
->d_inode
);
180 DEBUG("FT1000:%s:invalid file size\n", __FUNCTION__
);
181 filp_close(fd
, current
->files
);
185 pfwimg
= (char*)vmalloc ( fwimgsz
);
186 if (pfwimg
== NULL
) {
187 DEBUG("FT1000:%s:can not allocate memory for dsp image\n", __FUNCTION__
);
188 filp_close(fd
, current
->files
);
193 if (vfs_read(fd
, pfwimg
, fwimgsz
, &pos
) != fwimgsz
) {
195 DEBUG("FT1000:%s:failed to read firmware image\n",__FUNCTION__
);
196 filp_close(fd
, current
->files
);
201 filp_close(fd
, current
->files
);
207 //---------------------------------------------------------------------------
208 // Function: check_usb_db
210 // Parameters: struct ft1000_device - device structure
212 // Returns: 0 - success
214 // Description: This function checks if the doorbell register is cleared
218 //---------------------------------------------------------------------------
219 ULONG
check_usb_db (struct ft1000_device
*ft1000dev
)
229 status
= ft1000_read_register (ft1000dev
, &temp
, FT1000_REG_DOORBELL
);
230 DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n", temp
);
233 DEBUG("FT1000:Got checkusb doorbell\n");
234 status
= ft1000_write_register (ft1000dev
, 0x0080, FT1000_REG_DOORBELL
);
236 status
= ft1000_write_register (ft1000dev
, 0x0100, FT1000_REG_DOORBELL
);
238 status
= ft1000_write_register (ft1000dev
, 0x8000, FT1000_REG_DOORBELL
);
254 status
= ft1000_read_register (ft1000dev
, &temp
, FT1000_REG_DOORBELL
);
255 DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp
);
263 DEBUG("check_usb_db: door bell is cleared, return 0\n");
267 // Check if Card is present
268 status
= ft1000_read_register (ft1000dev
, &temp
, FT1000_REG_SUP_IMASK
);
269 if (temp
== 0x0000) {
273 status
= ft1000_read_register (ft1000dev
, &temp
, FT1000_REG_ASIC_ID
);
274 if (temp
== 0xffff) {
280 return HANDSHAKE_MAG_TIMEOUT_VALUE
;
284 //---------------------------------------------------------------------------
285 // Function: get_handshake
287 // Parameters: struct ft1000_device - device structure
288 // USHORT expected_value - the handshake value expected
290 // Returns: handshakevalue - success
291 // HANDSHAKE_TIMEOUT_VALUE - failure
293 // Description: This function gets the handshake and compare with the expected value
297 //---------------------------------------------------------------------------
298 USHORT
get_handshake(struct ft1000_device
*ft1000dev
, USHORT expected_value
)
303 PFT1000_INFO pft1000info
= netdev_priv(ft1000dev
->net
);
306 while (loopcnt
< 100)
310 // Need to clear downloader doorbell if Hartley ASIC
311 status
= ft1000_write_register (ft1000dev
, FT1000_DB_DNLD_RX
, FT1000_REG_DOORBELL
);
312 //DEBUG("FT1000:get_handshake:doorbell = 0x%x\n", temp);
313 if (pft1000info
->fcodeldr
)
315 DEBUG(" get_handshake: fcodeldr is %d\n", pft1000info
->fcodeldr
);
316 pft1000info
->fcodeldr
= 0;
317 status
= check_usb_db(ft1000dev
);
318 if (status
!= STATUS_SUCCESS
)
320 DEBUG("get_handshake: check_usb_db failed\n");
321 status
= STATUS_FAILURE
;
324 status
= ft1000_write_register (ft1000dev
, FT1000_DB_DNLD_RX
, FT1000_REG_DOORBELL
);
327 status
= ft1000_read_dpram16 (ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
, (PUCHAR
)&handshake
, 1);
328 //DEBUG("get_handshake: handshake is %x\n", tempx);
329 handshake
= ntohs(handshake
);
330 //DEBUG("get_handshake: after swap, handshake is %x\n", handshake);
332 // Need to clear downloader doorbell if Hartley ASIC
333 status
= ft1000_read_register (ft1000dev
, &temp
, FT1000_REG_DOORBELL
);
334 //DEBUG("FT1000:get_handshake:doorbell = 0x%x\n", temp);
337 if (temp
& FT1000_DB_DNLD_RX
)
339 //DEBUG("get_handshake: write FT1000_DB_DNLD_RX to doorbell register\n");
340 status
= ft1000_write_register(ft1000dev
, FT1000_DB_DNLD_RX
, FT1000_REG_DOORBELL
);
343 if (pft1000info
->fcodeldr
)
345 DEBUG(" get_handshake: fcodeldr is %d\n", pft1000info
->fcodeldr
);
346 pft1000info
->fcodeldr
= 0;
347 status
= check_usb_db(ft1000dev
);
348 if (status
!= STATUS_SUCCESS
)
350 DEBUG("get_handshake: check_usb_db failed\n");
351 status
= STATUS_FAILURE
;
355 status
= ft1000_read_register (ft1000dev
, &temp
, FT1000_REG_DOORBELL
);
356 //DEBUG("FT1000:get_handshake:doorbell = 0x%x\n", temp);
359 if (temp
& FT1000_DB_DNLD_RX
)
360 status
= ft1000_write_register(ft1000dev
,FT1000_DB_DNLD_RX
, FT1000_REG_DOORBELL
);
364 status
= ft1000_read_dpram16 (ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
, (PUCHAR
)&handshake
, 1);
365 //DEBUG("get_handshake: handshake is %x\n", tempx);
366 handshake
= ntohs(handshake
);
367 //DEBUG("get_handshake: after swap, handshake is %x\n", handshake);
374 return HANDSHAKE_TIMEOUT_VALUE
;
376 //DEBUG("get_handshake: handshake= %x\n", handshake);
377 if ((handshake
== expected_value
) || (handshake
== HANDSHAKE_RESET_VALUE_USB
))
379 //DEBUG("get_handshake: return handshake %x\n", handshake);
387 //DEBUG("HANDSHKE LOOP: %d\n", loopcnt);
391 //DEBUG("get_handshake: return handshake time out\n");
392 return HANDSHAKE_TIMEOUT_VALUE
;
395 //---------------------------------------------------------------------------
396 // Function: put_handshake
398 // Parameters: struct ft1000_device - device structure
399 // USHORT handshake_value - handshake to be written
403 // Description: This function write the handshake value to the handshake location
408 //---------------------------------------------------------------------------
409 void put_handshake(struct ft1000_device
*ft1000dev
,USHORT handshake_value
)
418 tempx
= (ULONG
)handshake_value
;
419 tempx
= ntohl(tempx
);
421 tempword
= (USHORT
)(tempx
& 0xffff);
422 status
= ft1000_write_dpram16 (ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
, tempword
, 0);
423 tempword
= (USHORT
)(tempx
>> 16);
424 status
= ft1000_write_dpram16 (ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
, tempword
, 1);
425 status
= ft1000_write_register(ft1000dev
, FT1000_DB_DNLD_TX
, FT1000_REG_DOORBELL
);
427 for (i
=0; i
<1000; i
++);
431 status
= ft1000_read_register (ft1000dev
, &tempword
, FT1000_REG_DOORBELL
);
432 if ((tempword
& FT1000_DB_DNLD_TX
) == 0)
437 DEBUG("FT1000:put_handshake could not clear Tx doorbell\n");
438 status
= ft1000_read_register (ft1000dev
, &tempword
, FT1000_REG_DOORBELL
);
439 DEBUG("FT1000:put_handshake:doorbell = 0x%x\n",tempword
);
445 USHORT
get_handshake_usb(struct ft1000_device
*ft1000dev
, USHORT expected_value
)
452 PFT1000_INFO pft1000info
= netdev_priv(ft1000dev
->net
);
455 while (loopcnt
< 100)
457 if (pft1000info
->usbboot
== 2) {
458 status
= ft1000_read_dpram32 (ft1000dev
, 0, (PUCHAR
)&(pft1000info
->tempbuf
[0]), 64);
459 for (temp
=0; temp
<16; temp
++)
460 DEBUG("tempbuf %d = 0x%x\n", temp
, pft1000info
->tempbuf
[temp
]);
461 status
= ft1000_read_dpram16 (ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
, (PUCHAR
)&handshake
, 1);
462 DEBUG("handshake from read_dpram16 = 0x%x\n", handshake
);
463 if (pft1000info
->dspalive
== pft1000info
->tempbuf
[6])
466 handshake
= pft1000info
->tempbuf
[1];
467 pft1000info
->dspalive
= pft1000info
->tempbuf
[6];
471 status
= ft1000_read_dpram16 (ft1000dev
, DWNLD_MAG1_HANDSHAKE_LOC
, (PUCHAR
)&handshake
, 1);
475 handshake
= ntohs(handshake
);
476 if ((handshake
== expected_value
) || (handshake
== HANDSHAKE_RESET_VALUE_USB
))
482 return HANDSHAKE_TIMEOUT_VALUE
;
485 void put_handshake_usb(struct ft1000_device
*ft1000dev
,USHORT handshake_value
)
489 for (i
=0; i
<1000; i
++);
492 //---------------------------------------------------------------------------
493 // Function: get_request_type
495 // Parameters: struct ft1000_device - device structure
497 // Returns: request type - success
499 // Description: This function returns the request type
503 //---------------------------------------------------------------------------
504 USHORT
get_request_type(struct ft1000_device
*ft1000dev
)
510 PFT1000_INFO pft1000info
= netdev_priv(ft1000dev
->net
);
512 if ( pft1000info
->bootmode
== 1)
514 status
= fix_ft1000_read_dpram32 (ft1000dev
, DWNLD_MAG1_TYPE_LOC
, (PUCHAR
)&tempx
);
515 tempx
= ntohl(tempx
);
522 status
= ft1000_read_dpram16 (ft1000dev
, DWNLD_MAG1_TYPE_LOC
, (PUCHAR
)&tempword
, 0);
525 status
= ft1000_read_dpram16 (ft1000dev
, DWNLD_MAG1_TYPE_LOC
, (PUCHAR
)&tempword
, 1);
526 tempx
|= (tempword
<< 16);
527 tempx
= ntohl(tempx
);
529 request_type
= (USHORT
)tempx
;
531 //DEBUG("get_request_type: request_type is %x\n", request_type);
536 USHORT
get_request_type_usb(struct ft1000_device
*ft1000dev
)
542 PFT1000_INFO pft1000info
= netdev_priv(ft1000dev
->net
);
543 if ( pft1000info
->bootmode
== 1)
545 status
= fix_ft1000_read_dpram32 (ft1000dev
, DWNLD_MAG1_TYPE_LOC
, (PUCHAR
)&tempx
);
546 tempx
= ntohl(tempx
);
550 if (pft1000info
->usbboot
== 2) {
551 tempx
= pft1000info
->tempbuf
[2];
552 tempword
= pft1000info
->tempbuf
[3];
556 status
= ft1000_read_dpram16 (ft1000dev
, DWNLD_MAG1_TYPE_LOC
, (PUCHAR
)&tempword
, 1);
558 tempx
|= (tempword
<< 16);
559 tempx
= ntohl(tempx
);
561 request_type
= (USHORT
)tempx
;
563 //DEBUG("get_request_type: request_type is %x\n", request_type);
568 //---------------------------------------------------------------------------
569 // Function: get_request_value
571 // Parameters: struct ft1000_device - device structure
573 // Returns: request value - success
575 // Description: This function returns the request value
579 //---------------------------------------------------------------------------
580 long get_request_value(struct ft1000_device
*ft1000dev
)
585 PFT1000_INFO pft1000info
= netdev_priv(ft1000dev
->net
);
588 if ( pft1000info
->bootmode
== 1)
590 status
= fix_ft1000_read_dpram32(ft1000dev
, DWNLD_MAG1_SIZE_LOC
, (PUCHAR
)&value
);
591 value
= ntohl(value
);
595 status
= ft1000_read_dpram16(ft1000dev
, DWNLD_MAG1_SIZE_LOC
, (PUCHAR
)&tempword
, 0);
597 status
= ft1000_read_dpram16(ft1000dev
, DWNLD_MAG1_SIZE_LOC
, (PUCHAR
)&tempword
, 1);
598 value
|= (tempword
<< 16);
599 value
= ntohl(value
);
603 //DEBUG("get_request_value: value is %x\n", value);
608 long get_request_value_usb(struct ft1000_device
*ft1000dev
)
613 PFT1000_INFO pft1000info
= netdev_priv(ft1000dev
->net
);
615 if (pft1000info
->usbboot
== 2) {
616 value
= pft1000info
->tempbuf
[4];
617 tempword
= pft1000info
->tempbuf
[5];
621 status
= ft1000_read_dpram16(ft1000dev
, DWNLD_MAG1_SIZE_LOC
, (PUCHAR
)&tempword
, 1);
624 value
|= (tempword
<< 16);
625 value
= ntohl(value
);
628 if (pft1000info
->usbboot
== 1)
629 pft1000info
->usbboot
= 2;
632 //DEBUG("get_request_value_usb: value is %x\n", value);
637 //---------------------------------------------------------------------------
638 // Function: put_request_value
640 // Parameters: struct ft1000_device - device structure
641 // long lvalue - value to be put into DPRAM location DWNLD_MAG1_SIZE_LOC
645 // Description: This function writes a value to DWNLD_MAG1_SIZE_LOC
649 //---------------------------------------------------------------------------
650 void put_request_value(struct ft1000_device
*ft1000dev
, long lvalue
)
655 tempx
= ntohl(lvalue
);
656 status
= fix_ft1000_write_dpram32(ft1000dev
, DWNLD_MAG1_SIZE_LOC
, (PUCHAR
)&tempx
);
660 //DEBUG("put_request_value: value is %x\n", lvalue);
666 //---------------------------------------------------------------------------
667 // Function: hdr_checksum
669 // Parameters: PPSEUDO_HDR pHdr - Pseudo header pointer
671 // Returns: checksum - success
673 // Description: This function returns the checksum of the pseudo header
677 //---------------------------------------------------------------------------
678 USHORT
hdr_checksum(PPSEUDO_HDR pHdr
)
680 USHORT
*usPtr
= (USHORT
*)pHdr
;
684 chksum
= ((((((usPtr
[0] ^ usPtr
[1]) ^ usPtr
[2]) ^ usPtr
[3]) ^
685 usPtr
[4]) ^ usPtr
[5]) ^ usPtr
[6]);
691 //---------------------------------------------------------------------------
692 // Function: write_blk
694 // Parameters: struct ft1000_device - device structure
695 // USHORT **pUsFile - DSP image file pointer in USHORT
696 // UCHAR **pUcFile - DSP image file pointer in UCHAR
697 // long word_length - lenght of the buffer to be written
700 // Returns: STATUS_SUCCESS - success
701 // STATUS_FAILURE - failure
703 // Description: This function writes a block of DSP image to DPRAM
707 //---------------------------------------------------------------------------
708 ULONG
write_blk (struct ft1000_device
*ft1000dev
, USHORT
**pUsFile
, UCHAR
**pUcFile
, long word_length
)
710 ULONG Status
= STATUS_SUCCESS
;
712 long temp_word_length
;
716 USHORT tempbuffer
[64];
717 USHORT resultbuffer
[64];
718 PFT1000_INFO pft1000info
= netdev_priv(ft1000dev
->net
);
720 //DEBUG("FT1000:download:start word_length = %d\n",(int)word_length);
721 dpram
= (USHORT
)DWNLD_MAG1_PS_HDR_LOC
;
722 tempword
= *(*pUsFile
);
724 Status
= ft1000_write_dpram16(ft1000dev
, dpram
, tempword
, 0);
725 tempword
= *(*pUsFile
);
727 Status
= ft1000_write_dpram16(ft1000dev
, dpram
++, tempword
, 1);
729 *pUcFile
= *pUcFile
+ 4;
731 tempword
= (USHORT
)word_length
;
732 word_length
= (word_length
/ 16) + 1;
733 pTempFile
= *pUsFile
;
734 temp_word_length
= word_length
;
735 for (; word_length
> 0; word_length
--) /* In words */
743 tempbuffer
[i
++] = *(*pUsFile
);
745 tempbuffer
[i
] = *(*pUsFile
);
747 *pUcFile
= *pUcFile
+ 4;
758 //DEBUG("write_blk: loopcnt is %d\n", loopcnt);
759 //DEBUG("write_blk: bootmode = %d\n", bootmode);
760 //DEBUG("write_blk: dpram = %x\n", dpram);
761 if (pft1000info
->bootmode
== 0)
764 Status
= ft1000_write_dpram32 (ft1000dev
, dpram
, (PUCHAR
)&tempbuffer
[0], 8);
766 Status
= ft1000_write_dpram32 (ft1000dev
, dpram
, (PUCHAR
)&tempbuffer
[0], 64);
772 Status
= ft1000_write_dpram32 (ft1000dev
, dpram
, (PUCHAR
)&tempbuffer
[0], 64);
773 if (Status
== STATUS_SUCCESS
)
775 // Work around for ASIC bit stuffing problem.
776 if ( (tempbuffer
[31] & 0xfe00) == 0xfe00)
778 Status
= ft1000_write_dpram32(ft1000dev
, dpram
+12, (PUCHAR
)&tempbuffer
[24], 64);
780 // Let's check the data written
781 Status
= ft1000_read_dpram32 (ft1000dev
, dpram
, (PUCHAR
)&resultbuffer
[0], 64);
782 if ( (tempbuffer
[31] & 0xfe00) == 0xfe00)
786 if (resultbuffer
[i
] != tempbuffer
[i
])
789 DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n");
791 Status
= STATUS_FAILURE
;
795 Status
= ft1000_read_dpram32 (ft1000dev
, dpram
+12, (PUCHAR
)&resultbuffer
[0], 64);
798 if (resultbuffer
[i
] != tempbuffer
[i
+24])
801 DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n");
803 Status
= STATUS_FAILURE
;
812 if (resultbuffer
[i
] != tempbuffer
[i
])
815 DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n");
817 Status
= STATUS_FAILURE
;
823 if (Status
== STATUS_SUCCESS
)
829 if (Status
!= STATUS_SUCCESS
)
831 DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer
[31]);
836 dpram
= dpram
+ loopcnt
;
842 static void usb_dnld_complete (struct urb
*urb
)
844 //DEBUG("****** usb_dnld_complete\n");
847 //---------------------------------------------------------------------------
848 // Function: write_blk_fifo
850 // Parameters: struct ft1000_device - device structure
851 // USHORT **pUsFile - DSP image file pointer in USHORT
852 // UCHAR **pUcFile - DSP image file pointer in UCHAR
853 // long word_length - lenght of the buffer to be written
856 // Returns: STATUS_SUCCESS - success
857 // STATUS_FAILURE - failure
859 // Description: This function writes a block of DSP image to DPRAM
863 //---------------------------------------------------------------------------
864 ULONG
write_blk_fifo (struct ft1000_device
*ft1000dev
, USHORT
**pUsFile
, UCHAR
**pUcFile
, long word_length
)
866 ULONG Status
= STATUS_SUCCESS
;
870 byte_length
= word_length
* 4;
873 aligncnt
= 4 - (byte_length
% 4);
876 byte_length
+= aligncnt
;
878 if (byte_length
&& ((byte_length
% 64) == 0)) {
882 if (byte_length
< 64)
886 pblk
= kzalloc(byte_length
, GFP_KERNEL
);
887 memcpy (pblk
, *pUcFile
, byte_length
);
889 pipe
= usb_sndbulkpipe (ft1000dev
->dev
, ft1000dev
->bulk_out_endpointAddr
);
891 Status
= usb_bulk_msg (ft1000dev
->dev
,
897 DEBUG("write_blk_fifo Status = 0x%8x Bytes Transfer = %d Data = 0x%x\n", Status
, cnt
, *pblk
);
901 usb_init_urb(ft1000dev
->tx_urb
);
902 memcpy (ft1000dev
->tx_buf
, *pUcFile
, byte_length
);
903 usb_fill_bulk_urb(ft1000dev
->tx_urb
,
905 usb_sndbulkpipe(ft1000dev
->dev
, ft1000dev
->bulk_out_endpointAddr
),
911 usb_submit_urb(ft1000dev
->tx_urb
, GFP_ATOMIC
);
914 *pUsFile
= *pUsFile
+ (word_length
<< 1);
915 *pUcFile
= *pUcFile
+ (word_length
<< 2);
920 //---------------------------------------------------------------------------
922 // Function: scram_dnldr
924 // Synopsis: Scramble downloader for Harley based ASIC via USB interface
926 // Arguments: pFileStart - pointer to start of file
927 // FileLength - file length
929 // Returns: status - return code
930 //---------------------------------------------------------------------------
932 u16
scram_dnldr(struct ft1000_device
*ft1000dev
, void *pFileStart
, ULONG FileLength
)
934 u16 Status
= STATUS_SUCCESS
;
939 //PPROV_RECORD pProvRecord;
940 PDSP_FILE_HDR pFileHdr
;
946 PDSP_FILE_HDR_5 pFileHdr5
;
947 PDSP_IMAGE_INFO_V6 pDspImageInfoV6
= NULL
;
948 long requested_version
;
949 BOOLEAN bGoodVersion
;
950 PDRVMSG pMailBoxData
;
951 USHORT
*pUsData
= NULL
;
952 USHORT
*pUsFile
= NULL
;
953 UCHAR
*pUcFile
= NULL
;
954 UCHAR
*pBootEnd
= NULL
, *pCodeEnd
= NULL
;
956 long loader_code_address
, loader_code_size
= 0;
957 long run_address
= 0, run_size
= 0;
960 ULONG image_chksum
= 0;
964 PPROV_RECORD pprov_record
;
965 FT1000_INFO
*pft1000info
= netdev_priv(ft1000dev
->net
);
967 DEBUG("Entered scram_dnldr...\n");
969 pft1000info
->fcodeldr
= 0;
970 pft1000info
->usbboot
= 0;
971 pft1000info
->dspalive
= 0xffff;
975 // Get version id of file, at first 4 bytes of file, for newer files.
978 uiState
= STATE_START_DWNLD
;
980 pFileHdr
= (PDSP_FILE_HDR
)pFileStart
;
981 pFileHdr5
= (PDSP_FILE_HDR_5
)pFileStart
;
983 ft1000_write_register (ft1000dev
, 0x800, FT1000_REG_MAG_WATERMARK
);
985 pUsFile
= (USHORT
*)(pFileStart
+ pFileHdr5
->loader_offset
);
986 pUcFile
= (UCHAR
*)(pFileStart
+ pFileHdr5
->loader_offset
);
988 pBootEnd
= (UCHAR
*)(pFileStart
+ pFileHdr5
->loader_code_end
);
990 loader_code_address
= pFileHdr5
->loader_code_address
;
991 loader_code_size
= pFileHdr5
->loader_code_size
;
992 bGoodVersion
= FALSE
;
994 while ((Status
== STATUS_SUCCESS
) && (uiState
!= STATE_DONE_FILE
))
998 case STATE_START_DWNLD
:
999 DEBUG("FT1000:STATE_START_DWNLD\n");
1000 if (pft1000info
->usbboot
)
1001 handshake
= get_handshake_usb(ft1000dev
, HANDSHAKE_DSP_BL_READY
);
1003 handshake
= get_handshake(ft1000dev
, HANDSHAKE_DSP_BL_READY
);
1005 if (handshake
== HANDSHAKE_DSP_BL_READY
)
1007 DEBUG("scram_dnldr: handshake is HANDSHAKE_DSP_BL_READY, call put_handshake(HANDSHAKE_DRIVER_READY)\n");
1008 put_handshake(ft1000dev
, HANDSHAKE_DRIVER_READY
);
1012 DEBUG("FT1000:download:Download error: Handshake failed\n");
1013 Status
= STATUS_FAILURE
;
1016 uiState
= STATE_BOOT_DWNLD
;
1020 case STATE_BOOT_DWNLD
:
1021 DEBUG("FT1000:STATE_BOOT_DWNLD\n");
1022 pft1000info
->bootmode
= 1;
1023 handshake
= get_handshake(ft1000dev
, HANDSHAKE_REQUEST
);
1024 if (handshake
== HANDSHAKE_REQUEST
)
1027 * Get type associated with the request.
1029 request
= get_request_type(ft1000dev
);
1032 case REQUEST_RUN_ADDRESS
:
1033 DEBUG("FT1000:REQUEST_RUN_ADDRESS\n");
1034 put_request_value(ft1000dev
, loader_code_address
);
1036 case REQUEST_CODE_LENGTH
:
1037 DEBUG("FT1000:REQUEST_CODE_LENGTH\n");
1038 put_request_value(ft1000dev
, loader_code_size
);
1040 case REQUEST_DONE_BL
:
1041 DEBUG("FT1000:REQUEST_DONE_BL\n");
1042 /* Reposition ptrs to beginning of code section */
1043 pUsFile
= (USHORT
*)(pBootEnd
);
1044 pUcFile
= (UCHAR
*)(pBootEnd
);
1045 //DEBUG("FT1000:download:pUsFile = 0x%8x\n", (int)pUsFile);
1046 //DEBUG("FT1000:download:pUcFile = 0x%8x\n", (int)pUcFile);
1047 uiState
= STATE_CODE_DWNLD
;
1048 pft1000info
->fcodeldr
= 1;
1050 case REQUEST_CODE_SEGMENT
:
1051 //DEBUG("FT1000:REQUEST_CODE_SEGMENT\n");
1052 word_length
= get_request_value(ft1000dev
);
1053 //DEBUG("FT1000:word_length = 0x%x\n", (int)word_length);
1055 if (word_length
> MAX_LENGTH
)
1057 DEBUG("FT1000:download:Download error: Max length exceeded\n");
1058 Status
= STATUS_FAILURE
;
1061 if ( (word_length
*2 + pUcFile
) > pBootEnd
)
1064 * Error, beyond boot code range.
1066 DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundry.\n",
1068 Status
= STATUS_FAILURE
;
1072 * Position ASIC DPRAM auto-increment pointer.
1074 dpram
= (USHORT
)DWNLD_MAG1_PS_HDR_LOC
;
1075 if (word_length
& 0x1)
1077 word_length
= word_length
/ 2;
1079 Status
= write_blk(ft1000dev
, &pUsFile
, &pUcFile
, word_length
);
1080 //DEBUG("write_blk returned %d\n", Status);
1083 DEBUG("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",request
);
1084 Status
= STATUS_FAILURE
;
1087 if (pft1000info
->usbboot
)
1088 put_handshake_usb(ft1000dev
, HANDSHAKE_RESPONSE
);
1090 put_handshake(ft1000dev
, HANDSHAKE_RESPONSE
);
1094 DEBUG("FT1000:download:Download error: Handshake failed\n");
1095 Status
= STATUS_FAILURE
;
1100 case STATE_CODE_DWNLD
:
1101 //DEBUG("FT1000:STATE_CODE_DWNLD\n");
1102 pft1000info
->bootmode
= 0;
1103 if (pft1000info
->usbboot
)
1104 handshake
= get_handshake_usb(ft1000dev
, HANDSHAKE_REQUEST
);
1106 handshake
= get_handshake(ft1000dev
, HANDSHAKE_REQUEST
);
1107 if (handshake
== HANDSHAKE_REQUEST
)
1110 * Get type associated with the request.
1112 if (pft1000info
->usbboot
)
1113 request
= get_request_type_usb(ft1000dev
);
1115 request
= get_request_type(ft1000dev
);
1118 case REQUEST_FILE_CHECKSUM
:
1119 DEBUG("FT1000:download:image_chksum = 0x%8x\n", image_chksum
);
1120 put_request_value(ft1000dev
, image_chksum
);
1122 case REQUEST_RUN_ADDRESS
:
1123 DEBUG("FT1000:download: REQUEST_RUN_ADDRESS\n");
1126 DEBUG("FT1000:download:run_address = 0x%8x\n", (int)run_address
);
1127 put_request_value(ft1000dev
, run_address
);
1131 DEBUG("FT1000:download:Download error: Got Run address request before image offset request.\n");
1132 Status
= STATUS_FAILURE
;
1136 case REQUEST_CODE_LENGTH
:
1137 DEBUG("FT1000:download:REQUEST_CODE_LENGTH\n");
1140 DEBUG("FT1000:download:run_size = 0x%8x\n", (int)run_size
);
1141 put_request_value(ft1000dev
, run_size
);
1145 DEBUG("FT1000:download:Download error: Got Size request before image offset request.\n");
1146 Status
= STATUS_FAILURE
;
1150 case REQUEST_DONE_CL
:
1152 pft1000info
->usbboot
= 3;
1154 /* Reposition ptrs to beginning of provisioning section */
1155 pUsFile
= (USHORT
*)(pFileStart
+ pFileHdr5
->commands_offset
);
1156 pUcFile
= (UCHAR
*)(pFileStart
+ pFileHdr5
->commands_offset
);
1157 uiState
= STATE_DONE_DWNLD
;
1159 case REQUEST_CODE_SEGMENT
:
1160 //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n");
1163 DEBUG("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
1164 Status
= STATUS_FAILURE
;
1168 word_length
= get_request_value_usb(ft1000dev
);
1169 //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
1170 if (word_length
> MAX_LENGTH
/2)
1172 word_length
= get_request_value(ft1000dev
);
1173 //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
1174 if (word_length
> MAX_LENGTH
)
1177 DEBUG("FT1000:download:Download error: Max length exceeded\n");
1178 Status
= STATUS_FAILURE
;
1181 if ( (word_length
*2 + pUcFile
) > pCodeEnd
)
1184 * Error, beyond boot code range.
1186 DEBUG("FT1000:download:Download error: Requested len=%d exceeds DSP code boundry.\n",
1188 Status
= STATUS_FAILURE
;
1192 * Position ASIC DPRAM auto-increment pointer.
1194 dpram
= (USHORT
)DWNLD_MAG1_PS_HDR_LOC
;
1195 if (word_length
& 0x1)
1197 word_length
= word_length
/ 2;
1200 write_blk_fifo (ft1000dev
, &pUsFile
, &pUcFile
, word_length
);
1201 if (pft1000info
->usbboot
== 0)
1202 pft1000info
->usbboot
++;
1203 if (pft1000info
->usbboot
== 1) {
1205 ft1000_write_dpram16 (ft1000dev
, DWNLD_MAG1_PS_HDR_LOC
, tempword
, 0);
1208 write_blk (ft1000dev
, &pUsFile
, &pUcFile
, word_length
);
1209 //ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)pUcFile, word_length);
1213 case REQUEST_MAILBOX_DATA
:
1214 DEBUG("FT1000:download: REQUEST_MAILBOX_DATA\n");
1215 // Convert length from byte count to word count. Make sure we round up.
1216 word_length
= (long)(pft1000info
->DSPInfoBlklen
+ 1)/2;
1217 put_request_value(ft1000dev
, word_length
);
1218 pMailBoxData
= (PDRVMSG
)&(pft1000info
->DSPInfoBlk
[0]);
1220 * Position ASIC DPRAM auto-increment pointer.
1224 pUsData
= (USHORT
*)&pMailBoxData
->data
[0];
1225 dpram
= (USHORT
)DWNLD_MAG1_PS_HDR_LOC
;
1226 if (word_length
& 0x1)
1229 word_length
= (word_length
/ 2);
1232 for (; word_length
> 0; word_length
--) /* In words */
1235 templong
= *pUsData
++;
1236 templong
|= (*pUsData
++ << 16);
1237 Status
= fix_ft1000_write_dpram32 (ft1000dev
, dpram
++, (PUCHAR
)&templong
);
1242 case REQUEST_VERSION_INFO
:
1243 DEBUG("FT1000:download:REQUEST_VERSION_INFO\n");
1244 word_length
= pFileHdr5
->version_data_size
;
1245 put_request_value(ft1000dev
, word_length
);
1247 * Position ASIC DPRAM auto-increment pointer.
1250 pUsFile
= (USHORT
*)(pFileStart
+ pFileHdr5
->version_data_offset
);
1253 dpram
= (USHORT
)DWNLD_MAG1_PS_HDR_LOC
;
1254 if (word_length
& 0x1)
1257 word_length
= (word_length
/ 2);
1260 for (; word_length
> 0; word_length
--) /* In words */
1263 templong
= ntohs(*pUsFile
++);
1264 temp
= ntohs(*pUsFile
++);
1265 templong
|= (temp
<< 16);
1266 Status
= fix_ft1000_write_dpram32 (ft1000dev
, dpram
++, (PUCHAR
)&templong
);
1271 case REQUEST_CODE_BY_VERSION
:
1272 DEBUG("FT1000:download:REQUEST_CODE_BY_VERSION\n");
1273 bGoodVersion
= FALSE
;
1274 requested_version
= get_request_value(ft1000dev
);
1276 pDspImageInfoV6
= (PDSP_IMAGE_INFO_V6
)(pFileStart
+ sizeof(DSP_FILE_HDR_5
));
1278 for (imageN
= 0; imageN
< pFileHdr5
->nDspImages
; imageN
++)
1281 temp
= (USHORT
)(pDspImageInfoV6
->version
);
1283 temp
= (USHORT
)(pDspImageInfoV6
->version
>> 16);
1284 templong
|= (temp
<< 16);
1285 if (templong
== (ULONG
)requested_version
)
1287 bGoodVersion
= TRUE
;
1288 DEBUG("FT1000:download: bGoodVersion is TRUE\n");
1289 pUsFile
= (USHORT
*)(pFileStart
+ pDspImageInfoV6
->begin_offset
);
1290 pUcFile
= (UCHAR
*)(pFileStart
+ pDspImageInfoV6
->begin_offset
);
1291 pCodeEnd
= (UCHAR
*)(pFileStart
+ pDspImageInfoV6
->end_offset
);
1292 run_address
= pDspImageInfoV6
->run_address
;
1293 run_size
= pDspImageInfoV6
->image_size
;
1294 image_chksum
= (ULONG
)pDspImageInfoV6
->checksum
;
1305 * Error, beyond boot code range.
1307 DEBUG("FT1000:download:Download error: Bad Version Request = 0x%x.\n",(int)requested_version
);
1308 Status
= STATUS_FAILURE
;
1314 DEBUG("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",request
);
1315 Status
= STATUS_FAILURE
;
1318 if (pft1000info
->usbboot
)
1319 put_handshake_usb(ft1000dev
, HANDSHAKE_RESPONSE
);
1321 put_handshake(ft1000dev
, HANDSHAKE_RESPONSE
);
1325 DEBUG("FT1000:download:Download error: Handshake failed\n");
1326 Status
= STATUS_FAILURE
;
1331 case STATE_DONE_DWNLD
:
1332 DEBUG("FT1000:download:Code loader is done...\n");
1333 uiState
= STATE_SECTION_PROV
;
1336 case STATE_SECTION_PROV
:
1337 DEBUG("FT1000:download:STATE_SECTION_PROV\n");
1338 pHdr
= (PPSEUDO_HDR
)pUcFile
;
1340 if (pHdr
->checksum
== hdr_checksum(pHdr
))
1342 if (pHdr
->portdest
!= 0x80 /* Dsp OAM */)
1344 uiState
= STATE_DONE_PROV
;
1347 usHdrLength
= ntohs(pHdr
->length
); /* Byte length for PROV records */
1349 // Get buffer for provisioning data
1350 pbuffer
= kmalloc ( (usHdrLength
+ sizeof(PSEUDO_HDR
) ), GFP_ATOMIC
);
1352 memcpy(pbuffer
, (void *)pUcFile
, (UINT
)(usHdrLength
+ sizeof(PSEUDO_HDR
)));
1353 // link provisioning data
1354 pprov_record
= kmalloc( sizeof(PROV_RECORD
), GFP_ATOMIC
);
1356 pprov_record
->pprov_data
= pbuffer
;
1357 list_add_tail (&pprov_record
->list
, &pft1000info
->prov_list
);
1358 // Move to next entry if available
1359 pUcFile
= (UCHAR
*)((UINT
)pUcFile
+ (UINT
)((usHdrLength
+ 1) & 0xFFFFFFFE) + sizeof(PSEUDO_HDR
));
1360 if ( (UINT
)(pUcFile
) - (UINT
)(pFileStart
) >= (UINT
)FileLength
) {
1361 uiState
= STATE_DONE_FILE
;
1366 Status
= STATUS_FAILURE
;
1370 Status
= STATUS_FAILURE
;
1375 /* Checksum did not compute */
1376 Status
= STATUS_FAILURE
;
1378 DEBUG("ft1000:download: after STATE_SECTION_PROV, uiState = %d, Status= %d\n", uiState
, Status
);
1381 case STATE_DONE_PROV
:
1382 DEBUG("FT1000:download:STATE_DONE_PROV\n");
1383 uiState
= STATE_DONE_FILE
;
1388 Status
= STATUS_FAILURE
;
1392 if (Status
!= STATUS_SUCCESS
) {
1397 // Check if Card is present
1398 Status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
1399 if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
1403 Status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
1404 if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
1411 DEBUG("Download exiting with status = 0x%8x\n", Status
);
1412 ft1000_write_register(ft1000dev
, FT1000_DB_DNLD_TX
, FT1000_REG_DOORBELL
);