Staging: ft1000: remove trailing whitespace
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / ft1000 / ft1000-usb / ft1000_download.c
blob93f75b1d4e5045d2ccd42a0314aac43d199ee670
1 //=====================================================
2 // CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
3 //
4 //
5 // This file is part of Express Card USB Driver
6 //
7 // $Id:
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"
20 #define FIFO_DNLD 1
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 {
90 long build_date;
91 long dsp_coff_date;
92 long loader_code_address;
93 long loader_code_size;
94 long loader_code_end;
95 long dsp_code_address;
96 long dsp_code_size;
97 long dsp_code_end;
98 long reserved[8];
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
132 unsigned short pad1;
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 //---------------------------------------------------------------------------
146 // Function: getfw
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
154 // Notes:
156 //---------------------------------------------------------------------------
157 char *getfw (char *fn, int *pimgsz)
159 struct file *fd;
160 mm_segment_t fs = get_fs();
161 loff_t pos;
162 char *pfwimg;
163 int fwimgsz;
165 set_fs(get_ds());
167 fd = filp_open(fn, 0, 0);
168 if ( IS_ERR(fd) )
170 DEBUG("FT1000:%s:can not open dsp image\n", __FUNCTION__);
171 set_fs(fs);
172 return NULL;
175 fwimgsz = i_size_read(fd->f_dentry->d_inode);
176 *pimgsz = fwimgsz;
178 if (fwimgsz <= 0)
180 DEBUG("FT1000:%s:invalid file size\n", __FUNCTION__);
181 filp_close(fd, current->files);
182 set_fs(fs);
183 return NULL;
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);
189 set_fs(fs);
190 return NULL;
192 pos = 0;
193 if (vfs_read(fd, pfwimg, fwimgsz, &pos) != fwimgsz) {
194 vfree(pfwimg);
195 DEBUG("FT1000:%s:failed to read firmware image\n",__FUNCTION__);
196 filp_close(fd, current->files);
197 set_fs(fs);
198 return NULL;
201 filp_close(fd, current->files);
202 set_fs(fs);
204 return pfwimg;
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
216 // Notes:
218 //---------------------------------------------------------------------------
219 ULONG check_usb_db (struct ft1000_device *ft1000dev)
221 int loopcnt;
222 USHORT temp;
223 ULONG status;
225 loopcnt = 0;
226 while (loopcnt < 10)
229 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL);
230 DEBUG("check_usb_db: read FT1000_REG_DOORBELL value is %x\n", temp);
231 if (temp & 0x0080)
233 DEBUG("FT1000:Got checkusb doorbell\n");
234 status = ft1000_write_register (ft1000dev, 0x0080, FT1000_REG_DOORBELL);
235 #if FIFO_DNLD
236 status = ft1000_write_register (ft1000dev, 0x0100, FT1000_REG_DOORBELL);
237 #endif
238 status = ft1000_write_register (ft1000dev, 0x8000, FT1000_REG_DOORBELL);
239 break;
241 else
243 loopcnt++;
244 msleep (10);
247 } //end of while
250 loopcnt = 0;
251 while (loopcnt < 20)
254 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL);
255 DEBUG("FT1000:check_usb_db:Doorbell = 0x%x\n", temp);
256 if (temp & 0x8000)
258 loopcnt++;
259 msleep (10);
261 else
263 DEBUG("check_usb_db: door bell is cleared, return 0\n");
264 return 0;
266 #if 0
267 // Check if Card is present
268 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_SUP_IMASK);
269 if (temp == 0x0000) {
270 break;
273 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_ASIC_ID);
274 if (temp == 0xffff) {
275 break;
277 #endif
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
295 // Notes:
297 //---------------------------------------------------------------------------
298 USHORT get_handshake(struct ft1000_device *ft1000dev, USHORT expected_value)
300 USHORT handshake;
301 int loopcnt;
302 ULONG status=0;
303 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
305 loopcnt = 0;
306 while (loopcnt < 100)
309 #if FIFO_DNLD
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;
322 break;
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);
331 #else
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);
335 if (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;
352 break;
355 status = ft1000_read_register (ft1000dev, &temp, FT1000_REG_DOORBELL);
356 //DEBUG("FT1000:get_handshake:doorbell = 0x%x\n", temp);
357 if (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);
369 } //end of if temp
370 #endif
373 if (status)
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);
380 return handshake;
382 else
384 loopcnt++;
385 msleep (10);
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
401 // Returns: none
403 // Description: This function write the handshake value to the handshake location
404 // in DPRAM
406 // Notes:
408 //---------------------------------------------------------------------------
409 void put_handshake(struct ft1000_device *ft1000dev,USHORT handshake_value)
411 ULONG tempx;
412 USHORT tempword;
413 int i;
414 ULONG status;
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);
426 #if FIFO_DNLD
427 for (i=0; i<1000; i++);
428 #else
429 for (i=0; i<10; i++)
431 status = ft1000_read_register (ft1000dev, &tempword, FT1000_REG_DOORBELL);
432 if ((tempword & FT1000_DB_DNLD_TX) == 0)
433 break;
435 if (i==10)
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);
441 #endif
445 USHORT get_handshake_usb(struct ft1000_device *ft1000dev, USHORT expected_value)
447 USHORT handshake;
448 int loopcnt;
449 USHORT temp;
450 ULONG status=0;
452 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
453 loopcnt = 0;
454 handshake = 0;
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])
464 handshake = 0;
465 else {
466 handshake = pft1000info->tempbuf[1];
467 pft1000info->dspalive = pft1000info->tempbuf[6];
470 else {
471 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1);
473 loopcnt++;
474 msleep(10);
475 handshake = ntohs(handshake);
476 if ((handshake == expected_value) || (handshake == HANDSHAKE_RESET_VALUE_USB))
478 return handshake;
482 return HANDSHAKE_TIMEOUT_VALUE;
485 void put_handshake_usb(struct ft1000_device *ft1000dev,USHORT handshake_value)
487 int i;
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
501 // Notes:
503 //---------------------------------------------------------------------------
504 USHORT get_request_type(struct ft1000_device *ft1000dev)
506 USHORT request_type;
507 ULONG status;
508 USHORT tempword;
509 ULONG tempx;
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);
517 else
519 #if FIFO_DNLD
520 tempx = 0;
521 #else
522 status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 0);
523 tempx = tempword;
524 #endif
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);
532 return request_type;
536 USHORT get_request_type_usb(struct ft1000_device *ft1000dev)
538 USHORT request_type;
539 ULONG status;
540 USHORT tempword;
541 ULONG tempx;
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);
548 else
550 if (pft1000info->usbboot == 2) {
551 tempx = pft1000info->tempbuf[2];
552 tempword = pft1000info->tempbuf[3];
554 else {
555 tempx = 0;
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);
564 return 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
577 // Notes:
579 //---------------------------------------------------------------------------
580 long get_request_value(struct ft1000_device *ft1000dev)
582 ULONG value;
583 USHORT tempword;
584 ULONG status;
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);
593 else
595 status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 0);
596 value = tempword;
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);
604 return value;
608 long get_request_value_usb(struct ft1000_device *ft1000dev)
610 ULONG value;
611 USHORT tempword;
612 ULONG status;
613 PFT1000_INFO pft1000info = netdev_priv(ft1000dev->net);
615 if (pft1000info->usbboot == 2) {
616 value = pft1000info->tempbuf[4];
617 tempword = pft1000info->tempbuf[5];
619 else {
620 value = 0;
621 status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 1);
624 value |= (tempword << 16);
625 value = ntohl(value);
627 #if FIFO_DNLD
628 if (pft1000info->usbboot == 1)
629 pft1000info->usbboot = 2;
630 #endif
632 //DEBUG("get_request_value_usb: value is %x\n", value);
633 return 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
643 // Returns: none
645 // Description: This function writes a value to DWNLD_MAG1_SIZE_LOC
647 // Notes:
649 //---------------------------------------------------------------------------
650 void put_request_value(struct ft1000_device *ft1000dev, long lvalue)
652 ULONG tempx;
653 ULONG status;
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
675 // Notes:
677 //---------------------------------------------------------------------------
678 USHORT hdr_checksum(PPSEUDO_HDR pHdr)
680 USHORT *usPtr = (USHORT *)pHdr;
681 USHORT chksum;
684 chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^
685 usPtr[4]) ^ usPtr[5]) ^ usPtr[6]);
687 return chksum;
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
698 // to DPRAM
700 // Returns: STATUS_SUCCESS - success
701 // STATUS_FAILURE - failure
703 // Description: This function writes a block of DSP image to DPRAM
705 // Notes:
707 //---------------------------------------------------------------------------
708 ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length)
710 ULONG Status = STATUS_SUCCESS;
711 USHORT dpram;
712 long temp_word_length;
713 int loopcnt, i, j;
714 USHORT *pTempFile;
715 USHORT tempword;
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);
723 (*pUsFile)++;
724 Status = ft1000_write_dpram16(ft1000dev, dpram, tempword, 0);
725 tempword = *(*pUsFile);
726 (*pUsFile)++;
727 Status = ft1000_write_dpram16(ft1000dev, dpram++, tempword, 1);
729 *pUcFile = *pUcFile + 4;
730 word_length--;
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 */
737 loopcnt = 0;
739 for (i=0; i<32; i++)
741 if (tempword != 0)
743 tempbuffer[i++] = *(*pUsFile);
744 (*pUsFile)++;
745 tempbuffer[i] = *(*pUsFile);
746 (*pUsFile)++;
747 *pUcFile = *pUcFile + 4;
748 loopcnt++;
749 tempword--;
751 else
753 tempbuffer[i++] = 0;
754 tempbuffer[i] = 0;
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)
763 if (dpram >= 0x3F4)
764 Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 8);
765 else
766 Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 64);
768 else
770 for (j=0; j<10; j++)
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)
784 for (i=0; i<28; i++)
786 if (resultbuffer[i] != tempbuffer[i])
788 //NdisMSleep (100);
789 DEBUG("FT1000:download:DPRAM write failed 1 during bootloading\n");
790 msleep(10);
791 Status = STATUS_FAILURE;
792 break;
795 Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (PUCHAR)&resultbuffer[0], 64);
796 for (i=0; i<16; i++)
798 if (resultbuffer[i] != tempbuffer[i+24])
800 //NdisMSleep (100);
801 DEBUG("FT1000:download:DPRAM write failed 2 during bootloading\n");
802 msleep(10);
803 Status = STATUS_FAILURE;
804 break;
808 else
810 for (i=0; i<32; i++)
812 if (resultbuffer[i] != tempbuffer[i])
814 //NdisMSleep (100);
815 DEBUG("FT1000:download:DPRAM write failed 3 during bootloading\n");
816 msleep(10);
817 Status = STATUS_FAILURE;
818 break;
823 if (Status == STATUS_SUCCESS)
824 break;
829 if (Status != STATUS_SUCCESS)
831 DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]);
832 break;
836 dpram = dpram + loopcnt;
839 return Status;
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
854 // to DPRAM
856 // Returns: STATUS_SUCCESS - success
857 // STATUS_FAILURE - failure
859 // Description: This function writes a block of DSP image to DPRAM
861 // Notes:
863 //---------------------------------------------------------------------------
864 ULONG write_blk_fifo (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length)
866 ULONG Status = STATUS_SUCCESS;
867 int byte_length;
868 long aligncnt;
870 byte_length = word_length * 4;
872 if (byte_length % 4)
873 aligncnt = 4 - (byte_length % 4);
874 else
875 aligncnt = 0;
876 byte_length += aligncnt;
878 if (byte_length && ((byte_length % 64) == 0)) {
879 byte_length += 4;
882 if (byte_length < 64)
883 byte_length = 68;
885 #if 0
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,
892 pipe,
893 pblk,
894 byte_length,
895 &cnt,
896 10);
897 DEBUG("write_blk_fifo Status = 0x%8x Bytes Transfer = %d Data = 0x%x\n", Status, cnt, *pblk);
899 kfree(pblk);
900 #else
901 usb_init_urb(ft1000dev->tx_urb);
902 memcpy (ft1000dev->tx_buf, *pUcFile, byte_length);
903 usb_fill_bulk_urb(ft1000dev->tx_urb,
904 ft1000dev->dev,
905 usb_sndbulkpipe(ft1000dev->dev, ft1000dev->bulk_out_endpointAddr),
906 ft1000dev->tx_buf,
907 byte_length,
908 usb_dnld_complete,
909 (void*)ft1000dev);
911 usb_submit_urb(ft1000dev->tx_urb, GFP_ATOMIC);
912 #endif
914 *pUsFile = *pUsFile + (word_length << 1);
915 *pUcFile = *pUcFile + (word_length << 2);
917 return Status;
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;
935 UINT uiState;
936 USHORT handshake;
937 PPSEUDO_HDR pHdr;
938 USHORT usHdrLength;
939 //PPROV_RECORD pProvRecord;
940 PDSP_FILE_HDR pFileHdr;
941 long word_length;
942 USHORT request;
943 USHORT temp;
944 USHORT tempword;
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;
955 int imageN;
956 long loader_code_address, loader_code_size = 0;
957 long run_address = 0, run_size = 0;
959 ULONG templong;
960 ULONG image_chksum = 0;
962 USHORT dpram = 0;
963 PUCHAR pbuffer;
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))
996 switch (uiState)
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);
1002 else
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);
1010 else
1012 DEBUG("FT1000:download:Download error: Handshake failed\n");
1013 Status = STATUS_FAILURE;
1016 uiState = STATE_BOOT_DWNLD;
1018 break;
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);
1030 switch (request)
1032 case REQUEST_RUN_ADDRESS:
1033 DEBUG("FT1000:REQUEST_RUN_ADDRESS\n");
1034 put_request_value(ft1000dev, loader_code_address);
1035 break;
1036 case REQUEST_CODE_LENGTH:
1037 DEBUG("FT1000:REQUEST_CODE_LENGTH\n");
1038 put_request_value(ft1000dev, loader_code_size);
1039 break;
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;
1049 break;
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);
1054 //NdisMSleep (100);
1055 if (word_length > MAX_LENGTH)
1057 DEBUG("FT1000:download:Download error: Max length exceeded\n");
1058 Status = STATUS_FAILURE;
1059 break;
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",
1067 (int)word_length);
1068 Status = STATUS_FAILURE;
1069 break;
1072 * Position ASIC DPRAM auto-increment pointer.
1074 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
1075 if (word_length & 0x1)
1076 word_length++;
1077 word_length = word_length / 2;
1079 Status = write_blk(ft1000dev, &pUsFile, &pUcFile, word_length);
1080 //DEBUG("write_blk returned %d\n", Status);
1081 break;
1082 default:
1083 DEBUG("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",request);
1084 Status = STATUS_FAILURE;
1085 break;
1087 if (pft1000info->usbboot)
1088 put_handshake_usb(ft1000dev, HANDSHAKE_RESPONSE);
1089 else
1090 put_handshake(ft1000dev, HANDSHAKE_RESPONSE);
1092 else
1094 DEBUG("FT1000:download:Download error: Handshake failed\n");
1095 Status = STATUS_FAILURE;
1098 break;
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);
1105 else
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);
1114 else
1115 request = get_request_type(ft1000dev);
1116 switch (request)
1118 case REQUEST_FILE_CHECKSUM:
1119 DEBUG("FT1000:download:image_chksum = 0x%8x\n", image_chksum);
1120 put_request_value(ft1000dev, image_chksum);
1121 break;
1122 case REQUEST_RUN_ADDRESS:
1123 DEBUG("FT1000:download: REQUEST_RUN_ADDRESS\n");
1124 if (bGoodVersion)
1126 DEBUG("FT1000:download:run_address = 0x%8x\n", (int)run_address);
1127 put_request_value(ft1000dev, run_address);
1129 else
1131 DEBUG("FT1000:download:Download error: Got Run address request before image offset request.\n");
1132 Status = STATUS_FAILURE;
1133 break;
1135 break;
1136 case REQUEST_CODE_LENGTH:
1137 DEBUG("FT1000:download:REQUEST_CODE_LENGTH\n");
1138 if (bGoodVersion)
1140 DEBUG("FT1000:download:run_size = 0x%8x\n", (int)run_size);
1141 put_request_value(ft1000dev, run_size);
1143 else
1145 DEBUG("FT1000:download:Download error: Got Size request before image offset request.\n");
1146 Status = STATUS_FAILURE;
1147 break;
1149 break;
1150 case REQUEST_DONE_CL:
1151 #if FIFO_DNLD
1152 pft1000info->usbboot = 3;
1153 #endif
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;
1158 break;
1159 case REQUEST_CODE_SEGMENT:
1160 //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n");
1161 if (!bGoodVersion)
1163 DEBUG("FT1000:download:Download error: Got Code Segment request before image offset request.\n");
1164 Status = STATUS_FAILURE;
1165 break;
1167 #if 0
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)
1171 #else
1172 word_length = get_request_value(ft1000dev);
1173 //DEBUG("FT1000:download:word_length = %d\n", (int)word_length);
1174 if (word_length > MAX_LENGTH)
1175 #endif
1177 DEBUG("FT1000:download:Download error: Max length exceeded\n");
1178 Status = STATUS_FAILURE;
1179 break;
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",
1187 (int)word_length);
1188 Status = STATUS_FAILURE;
1189 break;
1192 * Position ASIC DPRAM auto-increment pointer.
1194 dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC;
1195 if (word_length & 0x1)
1196 word_length++;
1197 word_length = word_length / 2;
1199 #if FIFO_DNLD
1200 write_blk_fifo (ft1000dev, &pUsFile, &pUcFile, word_length);
1201 if (pft1000info->usbboot == 0)
1202 pft1000info->usbboot++;
1203 if (pft1000info->usbboot == 1) {
1204 tempword = 0;
1205 ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_PS_HDR_LOC, tempword, 0);
1207 #else
1208 write_blk (ft1000dev, &pUsFile, &pUcFile, word_length);
1209 //ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)pUcFile, word_length);
1210 #endif
1211 break;
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)
1227 word_length++;
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);
1240 break;
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)
1255 word_length++;
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);
1269 break;
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);
1282 templong = temp;
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;
1295 break;
1297 pDspImageInfoV6++;
1300 } //end of for
1302 if (!bGoodVersion)
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;
1309 break;
1311 break;
1313 default:
1314 DEBUG("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",request);
1315 Status = STATUS_FAILURE;
1316 break;
1318 if (pft1000info->usbboot)
1319 put_handshake_usb(ft1000dev, HANDSHAKE_RESPONSE);
1320 else
1321 put_handshake(ft1000dev, HANDSHAKE_RESPONSE);
1323 else
1325 DEBUG("FT1000:download:Download error: Handshake failed\n");
1326 Status = STATUS_FAILURE;
1329 break;
1331 case STATE_DONE_DWNLD:
1332 DEBUG("FT1000:download:Code loader is done...\n");
1333 uiState = STATE_SECTION_PROV;
1334 break;
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;
1345 break;
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 );
1351 if (pbuffer) {
1352 memcpy(pbuffer, (void *)pUcFile, (UINT)(usHdrLength + sizeof(PSEUDO_HDR)));
1353 // link provisioning data
1354 pprov_record = kmalloc( sizeof(PROV_RECORD), GFP_ATOMIC );
1355 if (pprov_record) {
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;
1364 else {
1365 kfree(pbuffer);
1366 Status = STATUS_FAILURE;
1369 else {
1370 Status = STATUS_FAILURE;
1373 else
1375 /* Checksum did not compute */
1376 Status = STATUS_FAILURE;
1378 DEBUG("ft1000:download: after STATE_SECTION_PROV, uiState = %d, Status= %d\n", uiState, Status);
1379 break;
1381 case STATE_DONE_PROV:
1382 DEBUG("FT1000:download:STATE_DONE_PROV\n");
1383 uiState = STATE_DONE_FILE;
1384 break;
1387 default:
1388 Status = STATUS_FAILURE;
1389 break;
1390 } /* End Switch */
1392 if (Status != STATUS_SUCCESS) {
1393 break;
1396 /****
1397 // Check if Card is present
1398 Status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK);
1399 if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) {
1400 break;
1403 Status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID);
1404 if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) {
1405 break;
1407 ****/
1409 } /* End while */
1411 DEBUG("Download exiting with status = 0x%8x\n", Status);
1412 ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL);
1414 return Status;