c7292373a65f8fb4c873f4d1a7b05005834b29bd
[cascardo/linux.git] / drivers / staging / bcm / nvm.c
1 #include "headers.h"
2
3 #define DWORD unsigned int
4
5 static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset);
6 static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter);
7 static INT BcmGetActiveISO(PMINI_ADAPTER Adapter);
8 static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
9 static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
10 static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize);
11
12 static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
13 static INT BcmGetNvmSize(PMINI_ADAPTER Adapter);
14 static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
15 static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
16
17 static INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
18
19 static B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset);
20 static INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section);
21 static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
22
23 static INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
24 static INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
25 static INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
26 static INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
27
28 static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
29 static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
30 static INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
31 static INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, PUINT pBuff,
32                                           FLASH2X_SECTION_VAL eFlash2xSectionVal,
33                                           UINT uiOffset, UINT uiNumBytes);
34 static FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter);
35 static FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter);
36
37 static INT BeceemFlashBulkRead(
38         PMINI_ADAPTER Adapter,
39         PUINT pBuffer,
40         UINT uiOffset,
41         UINT uiNumBytes);
42
43 static INT BeceemFlashBulkWrite(
44         PMINI_ADAPTER Adapter,
45         PUINT pBuffer,
46         UINT uiOffset,
47         UINT uiNumBytes,
48         BOOLEAN bVerify);
49
50 static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter);
51
52 static INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData);
53
54 // Procedure:   ReadEEPROMStatusRegister
55 //
56 // Description: Reads the standard EEPROM Status Register.
57 //
58 // Arguments:
59 //              Adapter    - ptr to Adapter object instance
60 // Returns:
61 //              OSAL_STATUS_CODE
62 //
63 //-----------------------------------------------------------------------------
64
65 static UCHAR ReadEEPROMStatusRegister( PMINI_ADAPTER Adapter )
66 {
67         UCHAR uiData = 0;
68         DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
69         UINT uiStatus = 0;
70         UINT value = 0;
71         UINT value1 = 0;
72
73         /* Read the EEPROM status register */
74         value = EEPROM_READ_STATUS_REGISTER ;
75         wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
76
77         while ( dwRetries != 0 )
78         {
79                 value=0;
80                 uiStatus = 0 ;
81                 rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus));
82                 if(Adapter->device_removed == TRUE)
83                 {
84                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got removed hence exiting....");
85                         break;
86                 }
87
88                 /* Wait for Avail bit to be set. */
89                 if ( ( uiStatus & EEPROM_READ_DATA_AVAIL) != 0 )
90                 {
91                         /* Clear the Avail/Full bits - which ever is set. */
92                         value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
93                         wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
94
95                         value =0;
96                         rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
97                         uiData = (UCHAR)value;
98
99                         break;
100                 }
101
102                 dwRetries-- ;
103                 if ( dwRetries == 0 )
104                 {
105                          rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
106                          rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
107                          BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"0x3004 = %x 0x3008 = %x, retries = %d failed.\n",value,value1,  MAX_EEPROM_RETRIES*RETRIES_PER_DELAY);
108                         return uiData;
109                 }
110                 if( !(dwRetries%RETRIES_PER_DELAY) )
111                         msleep(1);
112                 uiStatus = 0 ;
113         }
114         return uiData;
115 } /* ReadEEPROMStatusRegister */
116
117 //-----------------------------------------------------------------------------
118 // Procedure:   ReadBeceemEEPROMBulk
119 //
120 // Description: This routine reads 16Byte data from EEPROM
121 //
122 // Arguments:
123 //              Adapter    - ptr to Adapter object instance
124 //      dwAddress   - EEPROM Offset to read the data from.
125 //      pdwData     - Pointer to double word where data needs to be stored in.  //              dwNumWords  - Number of words.  Valid values are 4 ONLY.
126 //
127 // Returns:
128 //              OSAL_STATUS_CODE:
129 //-----------------------------------------------------------------------------
130
131 INT ReadBeceemEEPROMBulk( PMINI_ADAPTER Adapter,
132                                                                            DWORD dwAddress,
133                                                                            DWORD *pdwData,
134                                                                            DWORD dwNumWords
135                                                                          )
136 {
137         DWORD dwIndex = 0;
138         DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
139         UINT uiStatus  = 0;
140         UINT value= 0;
141         UINT value1 = 0;
142         UCHAR *pvalue;
143
144         /* Flush the read and cmd queue. */
145         value=( EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH );
146         wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
147         value=0;
148         wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
149
150         /* Clear the Avail/Full bits. */
151         value=( EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL );
152         wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
153
154         value= dwAddress | ( (dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ );
155         wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
156
157         while ( dwRetries != 0 )
158                 {
159
160                 uiStatus = 0;
161                 rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
162                 if(Adapter->device_removed == TRUE)
163                 {
164                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got Removed.hence exiting from loop...");
165                         return -ENODEV;
166                 }
167
168                 /* If we are reading 16 bytes we want to be sure that the queue
169                  * is full before we read.  In the other cases we are ok if the
170                  * queue has data available */
171                 if ( dwNumWords == 4 )
172                 {
173                         if ( ( uiStatus & EEPROM_READ_DATA_FULL ) != 0 )
174                         {
175                                 /* Clear the Avail/Full bits - which ever is set. */
176                                 value = ( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) ) ;
177                                 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
178                                 break;
179                         }
180                 }
181                 else if ( dwNumWords == 1 )
182                 {
183
184                         if ( ( uiStatus & EEPROM_READ_DATA_AVAIL ) != 0 )
185                         {
186                                 /* We just got Avail and we have to read 32bits so we
187                                  * need this sleep for Cardbus kind of devices. */
188                                 if (Adapter->chip_id == 0xBECE0210 )
189                                                 udelay(800);
190
191                                 /* Clear the Avail/Full bits - which ever is set. */
192                                 value=( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) );
193                                 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
194                                 break;
195                         }
196                 }
197
198                 uiStatus = 0;
199
200                 dwRetries--;
201                 if(dwRetries == 0)
202                 {
203                         value=0;
204                         value1=0;
205                         rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
206                         rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
207                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x  retries = %d failed.\n", dwNumWords, value,  value1,  MAX_EEPROM_RETRIES*RETRIES_PER_DELAY);
208                         return STATUS_FAILURE;
209                 }
210                 if( !(dwRetries%RETRIES_PER_DELAY) )
211                         msleep(1);
212         }
213
214         for ( dwIndex = 0; dwIndex < dwNumWords ; dwIndex++ )
215         {
216                 /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */
217                 pvalue = (PUCHAR)(pdwData + dwIndex);
218
219                 value =0;
220                 rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
221
222                 pvalue[0] = value;
223
224                 value = 0;
225                 rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
226
227                 pvalue[1] = value;
228
229                 value =0;
230                 rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
231
232                 pvalue[2] = value;
233
234                 value = 0;
235                 rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
236
237                 pvalue[3] = value;
238         }
239
240         return STATUS_SUCCESS;
241 } /* ReadBeceemEEPROMBulk() */
242
243 //-----------------------------------------------------------------------------
244 // Procedure:   ReadBeceemEEPROM
245 //
246 // Description: This routine reads 4 data from EEPROM.  It uses 1 or 2 page
247 //                              reads to do this operation.
248 //
249 // Arguments:
250 //              Adapter     - ptr to Adapter object instance
251 //      uiOffset        - EEPROM Offset to read the data from.
252 //      pBuffer         - Pointer to word where data needs to be stored in.
253 //
254 // Returns:
255 //              OSAL_STATUS_CODE:
256 //-----------------------------------------------------------------------------
257
258 INT ReadBeceemEEPROM( PMINI_ADAPTER Adapter,
259                                                                    DWORD uiOffset,
260                                                                    DWORD *pBuffer
261                                                                  )
262 {
263         UINT uiData[8]          = {0};
264         UINT uiByteOffset       = 0;
265         UINT uiTempOffset       = 0;
266
267         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," ====> ");
268
269         uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
270         uiByteOffset = uiOffset - uiTempOffset;
271
272         ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
273
274         /* A word can overlap at most over 2 pages. In that case we read the
275          * next page too. */
276         if ( uiByteOffset > 12 )
277         {
278                 ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
279         }
280
281         memcpy( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4);
282
283         return STATUS_SUCCESS;
284 } /* ReadBeceemEEPROM() */
285
286
287
288 INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter)
289 {
290         INT Status;
291         unsigned char puMacAddr[6];
292
293         Status = BeceemNVMRead(Adapter,
294                         (PUINT)&puMacAddr[0],
295                         INIT_PARAMS_1_MACADDRESS_ADDRESS,
296                         MAC_ADDRESS_SIZE);
297
298         if(Status == STATUS_SUCCESS)
299                 memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
300
301         return Status;
302 }
303
304 //-----------------------------------------------------------------------------
305 // Procedure:   BeceemEEPROMBulkRead
306 //
307 // Description: Reads the EEPROM and returns the Data.
308 //
309 // Arguments:
310 //              Adapter    - ptr to Adapter object instance
311 //              pBuffer    - Buffer to store the data read from EEPROM
312 //              uiOffset   - Offset of EEPROM from where data should be read
313 //              uiNumBytes - Number of bytes to be read from the EEPROM.
314 //
315 // Returns:
316 //              OSAL_STATUS_SUCCESS - if EEPROM read is successfull.
317 //              <FAILURE>                       - if failed.
318 //-----------------------------------------------------------------------------
319
320 INT BeceemEEPROMBulkRead(
321         PMINI_ADAPTER Adapter,
322         PUINT pBuffer,
323         UINT uiOffset,
324         UINT uiNumBytes)
325 {
326         UINT uiData[4]            = {0};
327         //UINT uiAddress                  = 0;
328         UINT uiBytesRemaining = uiNumBytes;
329         UINT uiIndex              = 0;
330         UINT uiTempOffset         = 0;
331         UINT uiExtraBytes     = 0;
332         UINT uiFailureRetries = 0;
333         PUCHAR pcBuff = (PUCHAR)pBuffer;
334
335
336         if(uiOffset%MAX_RW_SIZE&& uiBytesRemaining)
337         {
338                 uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
339                 uiExtraBytes = uiOffset-uiTempOffset;
340                 ReadBeceemEEPROMBulk(Adapter,uiTempOffset,(PUINT)&uiData[0],4);
341                 if(uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes))
342                 {
343                         memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes);
344
345                         uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes);
346                         uiIndex += (MAX_RW_SIZE - uiExtraBytes);
347                         uiOffset += (MAX_RW_SIZE - uiExtraBytes);
348                 }
349                 else
350                 {
351                         memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining);
352                         uiIndex += uiBytesRemaining;
353                         uiOffset += uiBytesRemaining;
354                         uiBytesRemaining = 0;
355                 }
356
357
358         }
359
360
361         while(uiBytesRemaining && uiFailureRetries != 128)
362         {
363                 if(Adapter->device_removed )
364                 {
365                         return -1;
366                 }
367
368                 if(uiBytesRemaining >= MAX_RW_SIZE)
369                 {
370                         /* For the requests more than or equal to 16 bytes, use bulk
371                          * read function to make the access faster.
372                          * We read 4 Dwords of data */
373                         if(0 == ReadBeceemEEPROMBulk(Adapter,uiOffset,&uiData[0],4))
374                         {
375                                 memcpy(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE);
376                                 uiOffset += MAX_RW_SIZE;
377                                 uiBytesRemaining -= MAX_RW_SIZE;
378                                 uiIndex += MAX_RW_SIZE;
379                         }
380                         else
381                         {
382                                 uiFailureRetries++;
383                                 mdelay(3);//sleep for a while before retry...
384                         }
385                 }
386                 else if(uiBytesRemaining >= 4)
387                 {
388                         if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
389                         {
390                                 memcpy(pcBuff+uiIndex,&uiData[0],4);
391                                 uiOffset += 4;
392                                 uiBytesRemaining -= 4;
393                                 uiIndex +=4;
394                         }
395                         else
396                         {
397                                 uiFailureRetries++;
398                                 mdelay(3);//sleep for a while before retry...
399                         }
400                 }
401                 else
402                 { // Handle the reads less than 4 bytes...
403                         PUCHAR pCharBuff = (PUCHAR)pBuffer;
404                         pCharBuff += uiIndex;
405                         if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
406                         {
407                                 memcpy(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested.
408                                 uiBytesRemaining = 0;
409                         }
410                         else
411                         {
412                                 uiFailureRetries++;
413                                 mdelay(3);//sleep for a while before retry...
414                         }
415                 }
416
417         }
418
419         return 0;
420 }
421
422 //-----------------------------------------------------------------------------
423 // Procedure:   BeceemFlashBulkRead
424 //
425 // Description: Reads the FLASH and returns the Data.
426 //
427 // Arguments:
428 //              Adapter    - ptr to Adapter object instance
429 //              pBuffer    - Buffer to store the data read from FLASH
430 //              uiOffset   - Offset of FLASH from where data should be read
431 //              uiNumBytes - Number of bytes to be read from the FLASH.
432 //
433 // Returns:
434 //              OSAL_STATUS_SUCCESS - if FLASH read is successfull.
435 //              <FAILURE>                       - if failed.
436 //-----------------------------------------------------------------------------
437
438 static INT BeceemFlashBulkRead(
439         PMINI_ADAPTER Adapter,
440         PUINT pBuffer,
441         UINT uiOffset,
442         UINT uiNumBytes)
443 {
444         UINT uiIndex = 0;
445         UINT uiBytesToRead = uiNumBytes;
446         INT Status = 0;
447         UINT uiPartOffset = 0;
448
449         if(Adapter->device_removed )
450         {
451                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device Got Removed ");
452                 return -ENODEV;
453         }
454
455         //Adding flash Base address
456 //      uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
457 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
458   Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
459   return Status;
460 #endif
461
462         Adapter->SelectedChip = RESET_CHIP_SELECT;
463
464         if(uiOffset % MAX_RW_SIZE)
465         {
466                 BcmDoChipSelect(Adapter,uiOffset);
467                 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
468
469                 uiBytesToRead = MAX_RW_SIZE - (uiOffset%MAX_RW_SIZE);
470                 uiBytesToRead = MIN(uiNumBytes,uiBytesToRead);
471
472                 if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
473                 {
474                         Status = -1;
475                         Adapter->SelectedChip = RESET_CHIP_SELECT;
476                         return Status;
477                 }
478
479                 uiIndex += uiBytesToRead;
480                 uiOffset += uiBytesToRead;
481                 uiNumBytes -= uiBytesToRead;
482         }
483
484         while(uiNumBytes)
485         {
486                 BcmDoChipSelect(Adapter,uiOffset);
487                 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
488
489                 uiBytesToRead = MIN(uiNumBytes,MAX_RW_SIZE);
490
491                 if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
492                 {
493                         Status = -1;
494                         break;
495                 }
496
497
498                 uiIndex += uiBytesToRead;
499                 uiOffset += uiBytesToRead;
500                 uiNumBytes -= uiBytesToRead;
501
502         }
503         Adapter->SelectedChip = RESET_CHIP_SELECT;
504         return Status;
505 }
506
507 //-----------------------------------------------------------------------------
508 // Procedure:   BcmGetFlashSize
509 //
510 // Description: Finds the size of FLASH.
511 //
512 // Arguments:
513 //              Adapter    - ptr to Adapter object instance
514 //
515 // Returns:
516 //              UINT - size of the FLASH Storage.
517 //
518 //-----------------------------------------------------------------------------
519
520 static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter)
521 {
522         if(IsFlash2x(Adapter))
523                 return  (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER));
524         else
525                 return 32*1024;
526
527
528 }
529
530 //-----------------------------------------------------------------------------
531 // Procedure:   BcmGetEEPROMSize
532 //
533 // Description: Finds the size of EEPROM.
534 //
535 // Arguments:
536 //              Adapter    - ptr to Adapter object instance
537 //
538 // Returns:
539 //              UINT - size of the EEPROM Storage.
540 //
541 //-----------------------------------------------------------------------------
542
543 static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter)
544 {
545         UINT uiData = 0;
546         UINT uiIndex = 0;
547
548 //
549 // if EEPROM is present and already Calibrated,it will have
550 // 'BECM' string at 0th offset.
551 //      To find the EEPROM size read the possible boundaries of the
552 // EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will
553 // result in wrap around. So when we get the End of the EEPROM we will
554 // get 'BECM' string which is indeed at offset 0.
555 //
556         BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
557         if(uiData == BECM)
558         {
559                 for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
560                 {
561                         BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
562                         if(uiData == BECM)
563                         {
564                                 return uiIndex*1024;
565                         }
566                 }
567         }
568         else
569         {
570 //
571 // EEPROM may not be present or not programmed
572 //
573
574         uiData = 0xBABEFACE;
575                 if(0 == BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&uiData,0,4,TRUE))
576                 {
577                         uiData = 0;
578                         for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
579                         {
580                                 BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
581                                 if(uiData == 0xBABEFACE)
582                                 {
583                                         return uiIndex*1024;
584                                 }
585                         }
586                 }
587
588         }
589         return 0;
590 }
591
592
593 //-----------------------------------------------------------------------------
594 // Procedure:   FlashSectorErase
595 //
596 // Description: Finds the sector size of the FLASH.
597 //
598 // Arguments:
599 //              Adapter    - ptr to Adapter object instance
600 //              addr       - sector start address
601 //              numOfSectors - number of sectors to  be erased.
602 //
603 // Returns:
604 //              OSAL_STATUS_CODE
605 //
606 //-----------------------------------------------------------------------------
607
608
609 static INT FlashSectorErase(PMINI_ADAPTER Adapter,
610         UINT addr,
611         UINT numOfSectors)
612 {
613         UINT iIndex = 0, iRetries = 0;
614         UINT uiStatus = 0;
615         UINT value;
616
617         for(iIndex=0;iIndex<numOfSectors;iIndex++)
618         {
619                 value = 0x06000000;
620                 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
621
622                 value = (0xd8000000 | (addr & 0xFFFFFF));
623                 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
624                 iRetries = 0;
625
626                 do
627                 {
628                         value = (FLASH_CMD_STATUS_REG_READ << 24);
629                         if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
630                         {
631                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
632                                 return STATUS_FAILURE;
633                         }
634
635                         if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
636                         {
637                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
638                                 return STATUS_FAILURE;
639                         }
640                         iRetries++;
641                         //After every try lets make the CPU free for 10 ms. generally time taken by the
642                         //the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms
643                         //won't hamper performance in any case.
644                         msleep(10);
645                 }while((uiStatus & 0x1) && (iRetries < 400));
646
647                 if(uiStatus & 0x1)
648                 {
649                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"iRetries crossing the limit of 80000\n");
650                         return STATUS_FAILURE;
651                 }
652
653                 addr += Adapter->uiSectorSize;
654         }
655         return 0;
656 }
657 //-----------------------------------------------------------------------------
658 // Procedure:   flashByteWrite
659 //
660 // Description: Performs Byte by Byte write to flash
661 //
662 // Arguments:
663 //              Adapter   - ptr to Adapter object instance
664 //              uiOffset   - Offset of the flash where data needs to be written to.
665 //              pData   - Address of Data to be written.
666 // Returns:
667 //              OSAL_STATUS_CODE
668 //
669 //-----------------------------------------------------------------------------
670
671 static INT flashByteWrite(
672         PMINI_ADAPTER Adapter,
673         UINT uiOffset,
674         PVOID pData)
675 {
676
677         UINT uiStatus = 0;
678         INT  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
679
680         UINT value;
681         ULONG ulData = *(PUCHAR)pData;
682
683 //
684 // need not write 0xFF because write requires an erase and erase will
685 // make whole sector 0xFF.
686 //
687
688         if(0xFF == ulData)
689         {
690                 return STATUS_SUCCESS;
691         }
692
693 //      DumpDebug(NVM_RW,("flashWrite ====>\n"));
694         value = (FLASH_CMD_WRITE_ENABLE << 24);
695         if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
696         {
697                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
698                 return STATUS_FAILURE;
699         }
700         if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0 )
701         {
702                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
703                 return STATUS_FAILURE;
704         }
705         value = (0x02000000 | (uiOffset & 0xFFFFFF));
706         if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
707         {
708                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
709                 return STATUS_FAILURE;
710         }
711
712         //__udelay(950);
713
714         do
715         {
716                 value = (FLASH_CMD_STATUS_REG_READ << 24);
717                 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
718                 {
719                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
720                         return STATUS_FAILURE;
721                 }
722                 //__udelay(1);
723                 if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
724                 {
725                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
726                         return STATUS_FAILURE;
727                 }
728                 iRetries--;
729                 if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
730                          msleep(1);
731
732         }while((uiStatus & 0x1) && (iRetries  >0) );
733
734         if(uiStatus & 0x1)
735         {
736                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
737                 return STATUS_FAILURE ;
738         }
739
740         return STATUS_SUCCESS;
741 }
742
743
744
745 //-----------------------------------------------------------------------------
746 // Procedure:   flashWrite
747 //
748 // Description: Performs write to flash
749 //
750 // Arguments:
751 //              Adapter    - ptr to Adapter object instance
752 //              uiOffset   - Offset of the flash where data needs to be written to.
753 //              pData   - Address of Data to be written.
754 // Returns:
755 //              OSAL_STATUS_CODE
756 //
757 //-----------------------------------------------------------------------------
758
759 static INT flashWrite(
760         PMINI_ADAPTER Adapter,
761         UINT uiOffset,
762         PVOID pData)
763
764 {
765         //UINT uiStatus = 0;
766         //INT  iRetries = 0;
767         //UINT uiReadBack = 0;
768
769         UINT uiStatus = 0;
770         INT  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
771
772         UINT value;
773         UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
774 //
775 // need not write 0xFFFFFFFF because write requires an erase and erase will
776 // make whole sector 0xFFFFFFFF.
777 //
778         if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
779         {
780                 return 0;
781         }
782
783         value = (FLASH_CMD_WRITE_ENABLE << 24);
784
785         if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
786         {
787                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
788                 return STATUS_FAILURE;
789         }
790         if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
791         {
792                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
793                 return STATUS_FAILURE;
794         }
795
796         //__udelay(950);
797         do
798         {
799                 value = (FLASH_CMD_STATUS_REG_READ << 24);
800                 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
801                 {
802                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
803                         return STATUS_FAILURE;
804                 }
805                 //__udelay(1);
806                 if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
807                 {
808                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
809                         return STATUS_FAILURE;
810                 }
811
812                 iRetries--;
813                 //this will ensure that in there will be no changes in the current path.
814                 //currently one rdm/wrm takes 125 us.
815                 //Hence  125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay)
816                 //Hence current implementation cycle will intoduce no delay in current path
817                 if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
818                                 msleep(1);
819         }while((uiStatus & 0x1) && (iRetries > 0));
820
821         if(uiStatus & 0x1)
822         {
823                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
824                 return STATUS_FAILURE ;
825         }
826
827         return STATUS_SUCCESS;
828 }
829
830 //-----------------------------------------------------------------------------
831 // Procedure:   flashByteWriteStatus
832 //
833 // Description: Performs byte by byte write to flash with write done status check
834 //
835 // Arguments:
836 //              Adapter    - ptr to Adapter object instance
837 //              uiOffset    - Offset of the flash where data needs to be written to.
838 //              pData    - Address of the Data to be written.
839 // Returns:
840 //              OSAL_STATUS_CODE
841 //
842 //-----------------------------------------------------------------------------
843 static INT flashByteWriteStatus(
844         PMINI_ADAPTER Adapter,
845         UINT uiOffset,
846         PVOID pData)
847 {
848         UINT uiStatus = 0;
849         INT  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
850         ULONG ulData  = *(PUCHAR)pData;
851         UINT value;
852
853 //
854 // need not write 0xFFFFFFFF because write requires an erase and erase will
855 // make whole sector 0xFFFFFFFF.
856 //
857
858         if(0xFF == ulData)
859         {
860                 return STATUS_SUCCESS;
861         }
862
863         //      DumpDebug(NVM_RW,("flashWrite ====>\n"));
864
865         value = (FLASH_CMD_WRITE_ENABLE << 24);
866         if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
867         {
868                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
869                 return STATUS_SUCCESS;
870         }
871         if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0)
872         {
873                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
874                 return STATUS_FAILURE;
875         }
876         value = (0x02000000 | (uiOffset & 0xFFFFFF));
877         if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
878         {
879                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
880                 return STATUS_FAILURE;
881         }
882
883     //msleep(1);
884
885         do
886         {
887                 value = (FLASH_CMD_STATUS_REG_READ << 24);
888                 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
889                 {
890                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
891                         return STATUS_FAILURE;
892                 }
893                 //__udelay(1);
894                 if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
895                 {
896                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
897                         return STATUS_FAILURE;
898                 }
899
900                 iRetries--;
901                 if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
902                                 msleep(1);
903         }while((uiStatus & 0x1) && (iRetries > 0));
904
905         if(uiStatus & 0x1)
906         {
907                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
908                 return STATUS_FAILURE ;
909         }
910
911         return STATUS_SUCCESS;
912
913 }
914 //-----------------------------------------------------------------------------
915 // Procedure:   flashWriteStatus
916 //
917 // Description: Performs write to flash with write done status check
918 //
919 // Arguments:
920 //              Adapter    - ptr to Adapter object instance
921 //              uiOffset    - Offset of the flash where data needs to be written to.
922 //              pData    - Address of the Data to be written.
923 // Returns:
924 //              OSAL_STATUS_CODE
925 //
926 //-----------------------------------------------------------------------------
927
928 static INT flashWriteStatus(
929         PMINI_ADAPTER Adapter,
930         UINT uiOffset,
931         PVOID pData)
932 {
933         UINT uiStatus = 0;
934         INT  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
935         //UINT uiReadBack = 0;
936         UINT value;
937         UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
938
939 //
940 // need not write 0xFFFFFFFF because write requires an erase and erase will
941 // make whole sector 0xFFFFFFFF.
942 //
943         if (!memcmp(pData,uiErasePattern,MAX_RW_SIZE))
944         {
945                 return 0;
946         }
947
948         value = (FLASH_CMD_WRITE_ENABLE << 24);
949         if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
950         {
951                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
952                 return STATUS_FAILURE;
953         }
954         if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
955         {
956                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
957                 return STATUS_FAILURE;
958         }
959    // __udelay(1);
960
961         do
962         {
963                 value = (FLASH_CMD_STATUS_REG_READ << 24);
964                 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
965                 {
966                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
967                         return STATUS_FAILURE;
968                 }
969                 //__udelay(1);
970                 if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
971                 {
972                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
973                         return STATUS_FAILURE;
974                 }
975                 iRetries--;
976                 //this will ensure that in there will be no changes in the current path.
977                 //currently one rdm/wrm takes 125 us.
978                 //Hence  125 *2  * FLASH_PER_RETRIES_DELAY  >3 ms(worst case delay)
979                 //Hence current implementation cycle will intoduce no delay in current path
980                 if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
981                                 msleep(1);
982         }while((uiStatus & 0x1) && (iRetries >0));
983
984         if(uiStatus & 0x1)
985         {
986                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
987                 return STATUS_FAILURE ;
988         }
989
990         return STATUS_SUCCESS;
991 }
992
993 //-----------------------------------------------------------------------------
994 // Procedure:   BcmRestoreBlockProtectStatus
995 //
996 // Description: Restores the original block protection status.
997 //
998 // Arguments:
999 //              Adapter    - ptr to Adapter object instance
1000 //              ulWriteStatus   -Original status
1001 // Returns:
1002 //              <VOID>
1003 //
1004 //-----------------------------------------------------------------------------
1005
1006 static VOID BcmRestoreBlockProtectStatus(PMINI_ADAPTER Adapter,ULONG ulWriteStatus)
1007 {
1008         UINT value;
1009         value = (FLASH_CMD_WRITE_ENABLE<< 24);
1010         wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1011
1012         udelay(20);
1013         value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
1014         wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1015         udelay(20);
1016 }
1017 //-----------------------------------------------------------------------------
1018 // Procedure:   BcmFlashUnProtectBlock
1019 //
1020 // Description: UnProtects appropriate blocks for writing.
1021 //
1022 // Arguments:
1023 //              Adapter    - ptr to Adapter object instance
1024 //              uiOffset   - Offset of the flash where data needs to be written to. This should be Sector aligned.
1025 // Returns:
1026 //              ULONG   - Status value before UnProtect.
1027 //
1028 //-----------------------------------------------------------------------------
1029 static ULONG BcmFlashUnProtectBlock(PMINI_ADAPTER Adapter,UINT uiOffset, UINT uiLength)
1030 {
1031         ULONG ulStatus      = 0;
1032         ULONG ulWriteStatus = 0;
1033         UINT value;
1034         uiOffset = uiOffset&0x000FFFFF;
1035
1036 //
1037 // Implemented only for 1MB Flash parts.
1038 //
1039         if(FLASH_PART_SST25VF080B == Adapter->ulFlashID)
1040         {
1041         //
1042         // Get Current BP status.
1043         //
1044                 value = (FLASH_CMD_STATUS_REG_READ << 24);
1045                 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1046                 udelay(10);
1047         //
1048         // Read status will be WWXXYYZZ. We have to take only WW.
1049         //
1050                 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
1051                 ulStatus >>= 24;
1052                 ulWriteStatus = ulStatus;
1053
1054         //
1055         // Bits [5-2] give current block level protection status.
1056         // Bit5: BP3 - DONT CARE
1057         // BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4
1058         //                4 - UPPER 1/2. 5 to 7 - ALL BLOCKS
1059         //
1060
1061                 if(ulStatus)
1062                 {
1063                         if((uiOffset+uiLength) <= 0x80000)
1064                         {
1065                         //
1066                         // Offset comes in lower half of 1MB. Protect the upper half.
1067                         // Clear BP1 and BP0 and set BP2.
1068                         //
1069                                 ulWriteStatus |= (0x4<<2);
1070                                 ulWriteStatus &= ~(0x3<<2);
1071                         }
1072                         else if((uiOffset+uiLength) <= 0xC0000)
1073                         {
1074                         //
1075                         // Offset comes below Upper 1/4. Upper 1/4 can be protected.
1076                         //  Clear BP2 and set BP1 and BP0.
1077                         //
1078                                 ulWriteStatus |= (0x3<<2);
1079                                 ulWriteStatus &= ~(0x1<<4);
1080                         }
1081                         else if((uiOffset+uiLength) <= 0xE0000)
1082                     {
1083                     //
1084                     // Offset comes below Upper 1/8. Upper 1/8 can be protected.
1085                     // Clear BP2 and BP0  and set BP1
1086                     //
1087                         ulWriteStatus |= (0x1<<3);
1088                         ulWriteStatus &= ~(0x5<<2);
1089
1090                     }
1091                     else if((uiOffset+uiLength) <= 0xF0000)
1092                     {
1093                     //
1094                     // Offset comes below Upper 1/16. Only upper 1/16 can be protected.
1095                     // Set BP0 and Clear BP2,BP1.
1096                     //
1097                         ulWriteStatus |= (0x1<<2);
1098                         ulWriteStatus &= ~(0x3<<3);
1099                     }
1100                     else
1101                     {
1102                     //
1103                     // Unblock all.
1104                     // Clear BP2,BP1 and BP0.
1105                     //
1106                         ulWriteStatus &= ~(0x7<<2);
1107                     }
1108
1109                         value = (FLASH_CMD_WRITE_ENABLE<< 24);
1110                         wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1111                         udelay(20);
1112                         value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
1113                         wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1114                         udelay(20);
1115
1116                 }
1117
1118         }
1119         return ulStatus;
1120 }
1121 //-----------------------------------------------------------------------------
1122 // Procedure:   BeceemFlashBulkWrite
1123 //
1124 // Description: Performs write to the flash
1125 //
1126 // Arguments:
1127 //              Adapter    - ptr to Adapter object instance
1128 //              pBuffer         - Data to be written.
1129 //              uiOffset   - Offset of the flash where data needs to be written to.
1130 //              uiNumBytes - Number of bytes to be written.
1131 //              bVerify    - read verify flag.
1132 // Returns:
1133 //              OSAL_STATUS_CODE
1134 //
1135 //-----------------------------------------------------------------------------
1136
1137 static INT BeceemFlashBulkWrite(
1138         PMINI_ADAPTER Adapter,
1139         PUINT pBuffer,
1140         UINT uiOffset,
1141         UINT uiNumBytes,
1142         BOOLEAN bVerify)
1143 {
1144         PCHAR  pTempBuff                        = NULL;
1145         PUCHAR pcBuffer             = (PUCHAR)pBuffer;
1146         UINT  uiIndex                           = 0;
1147         UINT  uiOffsetFromSectStart = 0;
1148         UINT  uiSectAlignAddr           = 0;
1149         UINT  uiCurrSectOffsetAddr      = 0;
1150         UINT  uiSectBoundary            = 0;
1151         UINT  uiNumSectTobeRead         = 0;
1152         UCHAR ucReadBk[16]              = {0};
1153         ULONG ulStatus              = 0;
1154         INT Status                                      = STATUS_SUCCESS;
1155         UINT uiTemp                             = 0;
1156         UINT index                                      = 0;
1157         UINT uiPartOffset                       = 0;
1158
1159 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1160   Status = bcmflash_raw_write((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
1161   return Status;
1162 #endif
1163
1164         uiOffsetFromSectStart   = uiOffset & ~(Adapter->uiSectorSize - 1);
1165
1166         //Adding flash Base address
1167 //      uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
1168
1169         uiSectAlignAddr                 = uiOffset & ~(Adapter->uiSectorSize - 1);
1170         uiCurrSectOffsetAddr    = uiOffset & (Adapter->uiSectorSize - 1);
1171         uiSectBoundary                  = uiSectAlignAddr + Adapter->uiSectorSize;
1172
1173         pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
1174         if(NULL == pTempBuff)
1175                 goto BeceemFlashBulkWrite_EXIT;
1176 //
1177 // check if the data to be written is overlapped accross sectors
1178 //
1179         if(uiOffset+uiNumBytes < uiSectBoundary)
1180         {
1181                 uiNumSectTobeRead = 1;
1182         }
1183         else
1184         {
1185                 //      Number of sectors  = Last sector start address/First sector start address
1186                 uiNumSectTobeRead =  (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
1187                 if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
1188                 {
1189                         uiNumSectTobeRead++;
1190                 }
1191         }
1192         //Check whether Requested sector is writable or not in case of flash2x write. But if  write call is
1193         // for DSD calibration, allow it without checking of sector permission
1194
1195         if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE))
1196         {
1197                 index = 0;
1198                 uiTemp = uiNumSectTobeRead ;
1199                 while(uiTemp)
1200                 {
1201                          if(IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE)
1202                          {
1203                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%X> is not writable",
1204                                                                                         (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
1205                                 Status = SECTOR_IS_NOT_WRITABLE;
1206                                 goto BeceemFlashBulkWrite_EXIT;
1207                          }
1208                          uiTemp = uiTemp - 1;
1209                          index = index + 1 ;
1210                 }
1211         }
1212         Adapter->SelectedChip = RESET_CHIP_SELECT;
1213         while(uiNumSectTobeRead)
1214         {
1215                 //do_gettimeofday(&tv1);
1216                 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nTime In start of write :%ld ms\n",(tv1.tv_sec *1000 + tv1.tv_usec /1000));
1217                 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1218
1219                 BcmDoChipSelect(Adapter,uiSectAlignAddr);
1220
1221                 if(0 != BeceemFlashBulkRead(Adapter,
1222                                                 (PUINT)pTempBuff,
1223                                                 uiOffsetFromSectStart,
1224                                                 Adapter->uiSectorSize))
1225                 {
1226                         Status = -1;
1227                         goto BeceemFlashBulkWrite_EXIT;
1228                 }
1229
1230                 //do_gettimeofday(&tr);
1231                 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Read :%ld ms\n", (tr.tv_sec *1000 + tr.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000));
1232
1233                 ulStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);
1234
1235
1236                 if(uiNumSectTobeRead > 1)
1237                 {
1238
1239                         memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
1240                         pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
1241                         uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
1242                 }
1243                 else
1244                 {
1245                                 memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
1246                 }
1247
1248                 if(IsFlash2x(Adapter))
1249                 {
1250                         SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart);
1251                 }
1252
1253                 FlashSectorErase(Adapter,uiPartOffset,1);
1254                 //do_gettimeofday(&te);
1255                 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000));
1256
1257                 for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize)
1258                 {
1259                         if(Adapter->device_removed)
1260                         {
1261                                 Status = -1;
1262                                 goto BeceemFlashBulkWrite_EXIT;
1263                         }
1264                         if(STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter,uiPartOffset+uiIndex,(&pTempBuff[uiIndex])))
1265                         {
1266                                 Status = -1;
1267                                 goto BeceemFlashBulkWrite_EXIT;
1268                         }
1269                 }
1270
1271                 //do_gettimeofday(&tw);
1272                 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write  to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000));
1273                 for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
1274                 {
1275                         if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
1276                         {
1277                                 if(Adapter->ulFlashWriteSize == 1)
1278                                 {
1279                                         UINT uiReadIndex = 0;
1280                                         for(uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++)
1281                                         {
1282                                                 if(ucReadBk[uiReadIndex] != pTempBuff[uiIndex+uiReadIndex])
1283                                                 {
1284                                                         if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex+uiReadIndex,&pTempBuff[uiIndex+uiReadIndex]))
1285                                                         {
1286                                                                 Status = STATUS_FAILURE;
1287                                                                 goto BeceemFlashBulkWrite_EXIT;
1288                                                         }
1289                                                 }
1290                                         }
1291                                 }
1292                                 else
1293                                 {
1294                                         if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
1295                                         {
1296                                                 if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex]))
1297                                                 {
1298                                                         Status = STATUS_FAILURE;
1299                                                         goto BeceemFlashBulkWrite_EXIT;
1300                                                 }
1301                                         }
1302                                 }
1303                         }
1304                 }
1305                 //do_gettimeofday(&twv);
1306                 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write  to Flash verification :%ld ms\n", (twv.tv_sec *1000 + twv.tv_usec/1000) - (tw.tv_sec *1000 + tw.tv_usec/1000));
1307
1308
1309                 if(ulStatus)
1310                 {
1311                         BcmRestoreBlockProtectStatus(Adapter,ulStatus);
1312                         ulStatus = 0;
1313                 }
1314
1315                 uiCurrSectOffsetAddr = 0;
1316                 uiSectAlignAddr = uiSectBoundary;
1317                 uiSectBoundary += Adapter->uiSectorSize;
1318                 uiOffsetFromSectStart += Adapter->uiSectorSize;
1319                 uiNumSectTobeRead--;
1320         }
1321         //do_gettimeofday(&tv2);
1322         //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000));
1323         //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by in Write is :%ld ms\n", (tv2.tv_sec *1000 + tv2.tv_usec/1000) - (tv1.tv_sec *1000 + tv1.tv_usec/1000));
1324 //
1325 // Cleanup.
1326 //
1327 BeceemFlashBulkWrite_EXIT:
1328         if(ulStatus)
1329         {
1330                 BcmRestoreBlockProtectStatus(Adapter,ulStatus);
1331         }
1332         
1333         kfree(pTempBuff);
1334
1335         Adapter->SelectedChip = RESET_CHIP_SELECT;
1336         return Status;
1337 }
1338
1339
1340 //-----------------------------------------------------------------------------
1341 // Procedure:   BeceemFlashBulkWriteStatus
1342 //
1343 // Description: Writes to Flash. Checks the SPI status after each write.
1344 //
1345 // Arguments:
1346 //              Adapter    - ptr to Adapter object instance
1347 //              pBuffer         - Data to be written.
1348 //              uiOffset   - Offset of the flash where data needs to be written to.
1349 //              uiNumBytes - Number of bytes to be written.
1350 //              bVerify    - read verify flag.
1351 // Returns:
1352 //              OSAL_STATUS_CODE
1353 //
1354 //-----------------------------------------------------------------------------
1355
1356 static INT BeceemFlashBulkWriteStatus(
1357         PMINI_ADAPTER Adapter,
1358         PUINT pBuffer,
1359         UINT uiOffset,
1360         UINT uiNumBytes,
1361         BOOLEAN bVerify)
1362 {
1363         PCHAR  pTempBuff                        = NULL;
1364         PUCHAR pcBuffer             = (PUCHAR)pBuffer;
1365         UINT  uiIndex                           = 0;
1366         UINT  uiOffsetFromSectStart = 0;
1367         UINT  uiSectAlignAddr           = 0;
1368         UINT  uiCurrSectOffsetAddr      = 0;
1369         UINT  uiSectBoundary            = 0;
1370         UINT  uiNumSectTobeRead         = 0;
1371         UCHAR ucReadBk[16]                      = {0};
1372         ULONG ulStatus              = 0;
1373         UINT  Status                            = STATUS_SUCCESS;
1374         UINT uiTemp                             = 0;
1375         UINT index                                      = 0;
1376         UINT uiPartOffset                       = 0;
1377
1378         uiOffsetFromSectStart   = uiOffset & ~(Adapter->uiSectorSize - 1);
1379
1380         //uiOffset += Adapter->ulFlashCalStart;
1381         //Adding flash Base address
1382 //      uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
1383
1384         uiSectAlignAddr                 = uiOffset & ~(Adapter->uiSectorSize - 1);
1385         uiCurrSectOffsetAddr    = uiOffset & (Adapter->uiSectorSize - 1);
1386         uiSectBoundary                  = uiSectAlignAddr + Adapter->uiSectorSize;
1387
1388         pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
1389         if(NULL == pTempBuff)
1390                 goto BeceemFlashBulkWriteStatus_EXIT;
1391
1392 //
1393 // check if the data to be written is overlapped accross sectors
1394 //
1395         if(uiOffset+uiNumBytes < uiSectBoundary)
1396         {
1397                 uiNumSectTobeRead = 1;
1398         }
1399         else
1400         {
1401 //      Number of sectors  = Last sector start address/First sector start address
1402                 uiNumSectTobeRead =  (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
1403                 if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
1404                 {
1405                         uiNumSectTobeRead++;
1406                 }
1407         }
1408
1409         if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE))
1410         {
1411                 index = 0;
1412                 uiTemp = uiNumSectTobeRead ;
1413                 while(uiTemp)
1414                 {
1415                          if(IsOffsetWritable(Adapter,uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE)
1416                          {
1417                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%x> is not writable",
1418                                                                                         (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
1419                                 Status = SECTOR_IS_NOT_WRITABLE;
1420                                 goto BeceemFlashBulkWriteStatus_EXIT;
1421                          }
1422                          uiTemp = uiTemp - 1;
1423                          index = index + 1 ;
1424                 }
1425         }
1426
1427         Adapter->SelectedChip = RESET_CHIP_SELECT;
1428         while(uiNumSectTobeRead)
1429         {
1430                 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1431
1432                 BcmDoChipSelect(Adapter,uiSectAlignAddr);
1433                 if(0 != BeceemFlashBulkRead(Adapter,
1434                                                 (PUINT)pTempBuff,
1435                                                 uiOffsetFromSectStart,
1436                                                 Adapter->uiSectorSize))
1437                 {
1438                         Status = -1;
1439                         goto BeceemFlashBulkWriteStatus_EXIT;
1440                 }
1441
1442                 ulStatus = BcmFlashUnProtectBlock(Adapter,uiOffsetFromSectStart,Adapter->uiSectorSize);
1443
1444                 if(uiNumSectTobeRead > 1)
1445                 {
1446
1447                         memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
1448                         pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
1449                         uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
1450                 }
1451                 else
1452                 {
1453                         memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
1454                 }
1455
1456                 if(IsFlash2x(Adapter))
1457                 {
1458                         SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart);
1459                 }
1460
1461                 FlashSectorErase(Adapter,uiPartOffset,1);
1462
1463                 for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize)
1464
1465                 {
1466                         if(Adapter->device_removed)
1467                         {
1468                                 Status = -1;
1469                                 goto BeceemFlashBulkWriteStatus_EXIT;
1470                         }
1471
1472                         if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex]))
1473                         {
1474                                 Status = -1;
1475                                 goto BeceemFlashBulkWriteStatus_EXIT;
1476                         }
1477                 }
1478
1479                 if(bVerify)
1480                 {
1481                         for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
1482                         {
1483
1484                                 if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
1485                                 {
1486                                         if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
1487                                         {
1488                                                 Status = STATUS_FAILURE;
1489                                                 goto BeceemFlashBulkWriteStatus_EXIT;
1490                                         }
1491
1492                                 }
1493
1494                         }
1495                 }
1496
1497                 if(ulStatus)
1498                 {
1499                         BcmRestoreBlockProtectStatus(Adapter,ulStatus);
1500                         ulStatus = 0;
1501                 }
1502
1503                 uiCurrSectOffsetAddr = 0;
1504                 uiSectAlignAddr = uiSectBoundary;
1505                 uiSectBoundary += Adapter->uiSectorSize;
1506                 uiOffsetFromSectStart += Adapter->uiSectorSize;
1507                 uiNumSectTobeRead--;
1508         }
1509 //
1510 // Cleanup.
1511 //
1512 BeceemFlashBulkWriteStatus_EXIT:
1513         if(ulStatus)
1514         {
1515                 BcmRestoreBlockProtectStatus(Adapter,ulStatus);
1516         }
1517
1518         kfree(pTempBuff);
1519         Adapter->SelectedChip = RESET_CHIP_SELECT;
1520         return Status;
1521
1522 }
1523
1524 //-----------------------------------------------------------------------------
1525 // Procedure:   PropagateCalParamsFromEEPROMToMemory
1526 //
1527 // Description: Dumps the calibration section of EEPROM to DDR.
1528 //
1529 // Arguments:
1530 //              Adapter    - ptr to Adapter object instance
1531 // Returns:
1532 //              OSAL_STATUS_CODE
1533 //
1534 //-----------------------------------------------------------------------------
1535
1536
1537 INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter)
1538 {
1539         PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL);
1540         UINT uiEepromSize = 0;
1541         UINT uiIndex = 0;
1542         UINT uiBytesToCopy = 0;
1543         UINT uiCalStartAddr = EEPROM_CALPARAM_START;
1544         UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1545         UINT value;
1546         INT Status = 0;
1547         if(pBuff == NULL)
1548         {
1549                 return -1;
1550         }
1551
1552         if(0 != BeceemEEPROMBulkRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET,4))
1553         {
1554
1555                 kfree(pBuff);
1556                 return -1;
1557         }
1558
1559         uiEepromSize >>= 16;
1560         if(uiEepromSize > 1024*1024)
1561         {
1562                 kfree(pBuff);
1563                 return -1;
1564         }
1565
1566
1567         uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
1568
1569         while(uiBytesToCopy)
1570         {
1571                 if(0 != BeceemEEPROMBulkRead(Adapter,(PUINT)pBuff,uiCalStartAddr,uiBytesToCopy))
1572                 {
1573                         Status = -1;
1574                         break;
1575                 }
1576                 wrm(Adapter,uiMemoryLoc,(PCHAR)(((PULONG)pBuff)+uiIndex),uiBytesToCopy);
1577                 uiMemoryLoc += uiBytesToCopy;
1578                 uiEepromSize -= uiBytesToCopy;
1579                 uiCalStartAddr += uiBytesToCopy;
1580                 uiIndex += uiBytesToCopy/4;
1581                 uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
1582
1583         }
1584         value = 0xbeadbead;
1585         wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-4,&value, sizeof(value));
1586         value = 0xbeadbead;
1587         wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-8,&value, sizeof(value));
1588         kfree(pBuff);
1589
1590         return Status;
1591
1592 }
1593
1594 //-----------------------------------------------------------------------------
1595 // Procedure:   PropagateCalParamsFromFlashToMemory
1596 //
1597 // Description: Dumps the calibration section of EEPROM to DDR.
1598 //
1599 // Arguments:
1600 //              Adapter    - ptr to Adapter object instance
1601 // Returns:
1602 //              OSAL_STATUS_CODE
1603 //
1604 //-----------------------------------------------------------------------------
1605
1606 INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter)
1607 {
1608         PCHAR pBuff, pPtr;
1609         UINT uiEepromSize = 0;
1610         UINT uiBytesToCopy = 0;
1611         //UINT uiIndex = 0;
1612         UINT uiCalStartAddr = EEPROM_CALPARAM_START;
1613         UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1614         UINT value;
1615         INT Status = 0;
1616 //
1617 // Write the signature first. This will ensure firmware does not access EEPROM.
1618 //
1619         value = 0xbeadbead;
1620         wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
1621         value = 0xbeadbead;
1622         wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
1623
1624         if(0 != BeceemNVMRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET, 4))
1625         {
1626                 return -1;
1627         }
1628         uiEepromSize = ntohl(uiEepromSize);
1629         uiEepromSize >>= 16;
1630
1631 //
1632 //      subtract the auto init section size
1633 //
1634         uiEepromSize -= EEPROM_CALPARAM_START;
1635
1636         if(uiEepromSize > 1024*1024)
1637         {
1638                 return -1;
1639         }
1640
1641         pBuff = kmalloc(uiEepromSize, GFP_KERNEL);
1642         if ( pBuff == NULL )
1643                 return -1;
1644
1645         if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize))
1646         {
1647                 kfree(pBuff);
1648                 return -1;
1649         }
1650
1651         pPtr = pBuff;
1652
1653         uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
1654
1655         while(uiBytesToCopy)
1656         {
1657                 Status = wrm(Adapter,uiMemoryLoc,(PCHAR)pPtr,uiBytesToCopy);
1658                 if(Status)
1659                 {
1660                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrm failed with status :%d",Status);
1661                         break;
1662                 }
1663
1664                 pPtr += uiBytesToCopy;
1665                 uiEepromSize -= uiBytesToCopy;
1666                 uiMemoryLoc += uiBytesToCopy;
1667                 uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
1668         }
1669
1670         kfree(pBuff);
1671         return Status;
1672
1673 }
1674
1675 //-----------------------------------------------------------------------------
1676 // Procedure:   BeceemEEPROMReadBackandVerify
1677 //
1678 // Description: Read back the data written and verifies.
1679 //
1680 // Arguments:
1681 //              Adapter       - ptr to Adapter object instance
1682 //              pBuffer             - Data to be written.
1683 //              uiOffset       - Offset of the flash where data needs to be written to.
1684 //              uiNumBytes - Number of bytes to be written.
1685 // Returns:
1686 //              OSAL_STATUS_CODE
1687 //
1688 //-----------------------------------------------------------------------------
1689
1690 static INT BeceemEEPROMReadBackandVerify(
1691         PMINI_ADAPTER Adapter,
1692         PUINT pBuffer,
1693         UINT uiOffset,
1694         UINT uiNumBytes)
1695 {
1696         UINT uiRdbk     = 0;
1697         UINT uiIndex    = 0;
1698         UINT uiData     = 0;
1699         UINT auiData[4] = {0};
1700
1701         while(uiNumBytes)
1702         {
1703                 if(Adapter->device_removed )
1704                 {
1705                         return -1;
1706                 }
1707
1708                 if(uiNumBytes >= MAX_RW_SIZE)
1709                 {// for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster.
1710                         BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);
1711
1712                         if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
1713                         {
1714                                 // re-write
1715                                 BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,MAX_RW_SIZE,FALSE);
1716                                 mdelay(3);
1717                                 BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);
1718
1719                                 if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
1720                                 {
1721                                         return -1;
1722                                 }
1723                         }
1724                         uiOffset += MAX_RW_SIZE;
1725                         uiNumBytes -= MAX_RW_SIZE;
1726                         uiIndex += 4;
1727
1728                 }
1729                 else if(uiNumBytes >= 4)
1730                 {
1731                         BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4);
1732                         if(uiData != pBuffer[uiIndex])
1733                         {
1734                                 //re-write
1735                                 BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,4,FALSE);
1736                                 mdelay(3);
1737                                 BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4);
1738                                 if(uiData != pBuffer[uiIndex])
1739                                 {
1740                                         return -1;
1741                                 }
1742                         }
1743                         uiOffset += 4;
1744                         uiNumBytes -= 4;
1745                         uiIndex++;
1746
1747                 }
1748                 else
1749                 { // Handle the reads less than 4 bytes...
1750                         uiData = 0;
1751                         memcpy(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes);
1752                         BeceemEEPROMBulkRead(Adapter,&uiRdbk,uiOffset,4);
1753
1754                         if(memcmp(&uiData, &uiRdbk, uiNumBytes))
1755                                 return -1;
1756
1757                         uiNumBytes = 0;
1758                 }
1759
1760         }
1761
1762         return 0;
1763 }
1764
1765 static VOID BcmSwapWord(UINT *ptr1) {
1766
1767         UINT  tempval = (UINT)*ptr1;
1768         char *ptr2 = (char *)&tempval;
1769         char *ptr = (char *)ptr1;
1770
1771         ptr[0] = ptr2[3];
1772         ptr[1] = ptr2[2];
1773         ptr[2] = ptr2[1];
1774         ptr[3] = ptr2[0];
1775 }
1776
1777 //-----------------------------------------------------------------------------
1778 // Procedure:   BeceemEEPROMWritePage
1779 //
1780 // Description: Performs page write (16bytes) to the EEPROM
1781 //
1782 // Arguments:
1783 //              Adapter       - ptr to Adapter object instance
1784 //              uiData            - Data to be written.
1785 //              uiOffset      - Offset of the EEPROM where data needs to be written to.
1786 // Returns:
1787 //              OSAL_STATUS_CODE
1788 //
1789 //-----------------------------------------------------------------------------
1790 static INT BeceemEEPROMWritePage( PMINI_ADAPTER Adapter, UINT uiData[], UINT uiOffset )
1791 {
1792         UINT uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
1793         UINT uiStatus = 0;
1794         UCHAR uiEpromStatus = 0;
1795         UINT value =0 ;
1796
1797         /* Flush the Write/Read/Cmd queues. */
1798         value = ( EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH );
1799         wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
1800         value = 0 ;
1801         wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
1802
1803         /* Clear the Empty/Avail/Full bits.  After this it has been confirmed
1804          * that the bit was cleared by reading back the register. See NOTE below.
1805          * We also clear the Read queues as we do a EEPROM status register read
1806          * later. */
1807         value = ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL ) ;
1808         wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
1809
1810         /* Enable write */
1811         value = EEPROM_WRITE_ENABLE ;
1812         wrmalt( Adapter, EEPROM_CMDQ_SPI_REG,&value, sizeof(value) );
1813
1814         /* We can write back to back 8bits * 16 into the queue and as we have
1815          * checked for the queue to be empty we can write in a burst. */
1816
1817         value = uiData[0];
1818         BcmSwapWord(&value);
1819         wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1820
1821         value = uiData[1];
1822         BcmSwapWord(&value);
1823         wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1824
1825         value = uiData[2];
1826         BcmSwapWord(&value);
1827         wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1828
1829         value = uiData[3];
1830         BcmSwapWord(&value);
1831         wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1832
1833         /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG
1834          * shows that we see 7 for the EEPROM data write.  Which means that
1835          * queue got full, also space is available as well as the queue is empty.
1836          * This may happen in sequence. */
1837         value =  EEPROM_16_BYTE_PAGE_WRITE | uiOffset ;
1838         wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value) );
1839
1840         /* Ideally we should loop here without tries and eventually succeed.
1841          * What we are checking if the previous write has completed, and this
1842          * may take time. We should wait till the Empty bit is set. */
1843         uiStatus = 0;
1844         rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
1845         while ( ( uiStatus & EEPROM_WRITE_QUEUE_EMPTY ) == 0 )
1846         {
1847                 uiRetries--;
1848                 if ( uiRetries == 0 )
1849                 {
1850                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY);
1851                         return STATUS_FAILURE ;
1852                 }
1853
1854                 if( !(uiRetries%RETRIES_PER_DELAY) )
1855                                         msleep(1);
1856
1857                 uiStatus = 0;
1858                 rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
1859                 if(Adapter->device_removed == TRUE)
1860                 {
1861                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem got removed hence exiting from loop....");
1862                         return -ENODEV;
1863                 }
1864
1865         }
1866
1867         if ( uiRetries != 0 )
1868         {
1869                 /* Clear the ones that are set - either, Empty/Full/Avail bits */
1870                 value = ( uiStatus & ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL ) );
1871                 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
1872         }
1873
1874         /* Here we should check if the EEPROM status register is correct before
1875          * proceeding. Bit 0 in the EEPROM Status register should be 0 before
1876          * we proceed further.  A 1 at Bit 0 indicates that the EEPROM is busy
1877          * with the previous write. Note also that issuing this read finally
1878          * means the previous write to the EEPROM has completed. */
1879         uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
1880         uiEpromStatus = 0;
1881         while ( uiRetries != 0 )
1882         {
1883                 uiEpromStatus = ReadEEPROMStatusRegister( Adapter) ;
1884                 if(Adapter->device_removed == TRUE)
1885                 {
1886                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
1887                         return -ENODEV;
1888                 }
1889                 if ( ( EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus ) == 0 )
1890                 {
1891                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY- uiRetries) );
1892                         return STATUS_SUCCESS ;
1893                 }
1894                 uiRetries--;
1895                 if ( uiRetries == 0 )
1896                 {
1897                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY);
1898                         return STATUS_FAILURE ;
1899                 }
1900                 uiEpromStatus = 0;
1901                 if( !(uiRetries%RETRIES_PER_DELAY) )
1902                                 msleep(1);
1903         }
1904
1905         return STATUS_SUCCESS ;
1906 } /* BeceemEEPROMWritePage */
1907
1908
1909 //-----------------------------------------------------------------------------
1910 // Procedure:   BeceemEEPROMBulkWrite
1911 //
1912 // Description: Performs write to the EEPROM
1913 //
1914 // Arguments:
1915 //              Adapter       - ptr to Adapter object instance
1916 //              pBuffer             - Data to be written.
1917 //              uiOffset       - Offset of the EEPROM where data needs to be written to.
1918 //              uiNumBytes - Number of bytes to be written.
1919 //              bVerify        - read verify flag.
1920 // Returns:
1921 //              OSAL_STATUS_CODE
1922 //
1923 //-----------------------------------------------------------------------------
1924
1925 INT BeceemEEPROMBulkWrite(
1926         PMINI_ADAPTER Adapter,
1927         PUCHAR pBuffer,
1928         UINT uiOffset,
1929         UINT uiNumBytes,
1930         BOOLEAN bVerify)
1931 {
1932         UINT  uiBytesToCopy = uiNumBytes;
1933         //UINT  uiRdbk          = 0;
1934         UINT  uiData[4]         = {0};
1935         UINT  uiIndex           = 0;
1936         UINT  uiTempOffset  = 0;
1937         UINT  uiExtraBytes  = 0;
1938         //PUINT puiBuffer       = (PUINT)pBuffer;
1939         //INT value;
1940
1941         if(uiOffset%MAX_RW_SIZE && uiBytesToCopy)
1942         {
1943                 uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
1944                 uiExtraBytes = uiOffset-uiTempOffset;
1945
1946
1947                 BeceemEEPROMBulkRead(Adapter,&uiData[0],uiTempOffset,MAX_RW_SIZE);
1948
1949                 if(uiBytesToCopy >= (16 -uiExtraBytes))
1950                 {
1951                         memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes);
1952
1953                         if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
1954                                         return STATUS_FAILURE;
1955
1956                         uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes);
1957                         uiIndex += (MAX_RW_SIZE - uiExtraBytes);
1958                         uiOffset += (MAX_RW_SIZE - uiExtraBytes);
1959                 }
1960                 else
1961                 {
1962                         memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy);
1963
1964                         if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
1965                                         return STATUS_FAILURE;
1966
1967                         uiIndex += uiBytesToCopy;
1968                         uiOffset += uiBytesToCopy;
1969                         uiBytesToCopy = 0;
1970                 }
1971
1972
1973         }
1974
1975         while(uiBytesToCopy)
1976         {
1977                 if(Adapter->device_removed)
1978                 {
1979                         return -1;
1980                 }
1981
1982                 if(uiBytesToCopy >= MAX_RW_SIZE)
1983                 {
1984
1985                         if (STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, (PUINT) &pBuffer[uiIndex], uiOffset ) )
1986                                                 return STATUS_FAILURE;
1987
1988                         uiIndex += MAX_RW_SIZE;
1989                         uiOffset += MAX_RW_SIZE;
1990                         uiBytesToCopy   -= MAX_RW_SIZE;
1991                 }
1992                 else
1993                 {
1994         //
1995         // To program non 16byte aligned data, read 16byte and then update.
1996         //
1997                         BeceemEEPROMBulkRead(Adapter,&uiData[0],uiOffset,16);
1998                         memcpy(&uiData[0],pBuffer+uiIndex,uiBytesToCopy);
1999
2000
2001                         if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiOffset ) )
2002                                         return STATUS_FAILURE;
2003                         uiBytesToCopy = 0;
2004                 }
2005
2006         }
2007
2008         return 0;
2009 }
2010
2011 //-----------------------------------------------------------------------------
2012 // Procedure:   BeceemNVMRead
2013 //
2014 // Description: Reads n number of bytes from NVM.
2015 //
2016 // Arguments:
2017 //              Adapter      - ptr to Adapter object instance
2018 //              pBuffer       - Buffer to store the data read from NVM
2019 //              uiOffset       - Offset of NVM from where data should be read
2020 //              uiNumBytes - Number of bytes to be read from the NVM.
2021 //
2022 // Returns:
2023 //              OSAL_STATUS_SUCCESS - if NVM read is successfull.
2024 //              <FAILURE>                       - if failed.
2025 //-----------------------------------------------------------------------------
2026
2027 INT BeceemNVMRead(
2028         PMINI_ADAPTER Adapter,
2029         PUINT pBuffer,
2030         UINT uiOffset,
2031         UINT uiNumBytes)
2032 {
2033         INT Status = 0;
2034 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2035         UINT uiTemp = 0, value;
2036 #endif
2037
2038         if(Adapter->eNVMType == NVM_FLASH)
2039         {
2040                 if(Adapter->bFlashRawRead == FALSE)
2041                 {
2042                         if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
2043                                 return vendorextnReadSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes);
2044                         uiOffset = uiOffset+ Adapter->ulFlashCalStart ;
2045                 }
2046 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
2047                 Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
2048 #else
2049
2050                 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2051                 value = 0;
2052                 wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
2053                 Status = BeceemFlashBulkRead(Adapter,
2054                                                 pBuffer,
2055                                                 uiOffset,
2056                                                 uiNumBytes);
2057                 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2058 #endif
2059         }
2060         else if(Adapter->eNVMType == NVM_EEPROM)
2061         {
2062                 Status = BeceemEEPROMBulkRead(Adapter,
2063                                         pBuffer,
2064                                         uiOffset,
2065                                         uiNumBytes);
2066         }
2067         else
2068         {
2069                 Status = -1;
2070         }
2071         return Status;
2072 }
2073
2074 //-----------------------------------------------------------------------------
2075 // Procedure:   BeceemNVMWrite
2076 //
2077 // Description: Writes n number of bytes to NVM.
2078 //
2079 // Arguments:
2080 //              Adapter      - ptr to Adapter object instance
2081 //              pBuffer       - Buffer contains the data to be written.
2082 //              uiOffset       - Offset of NVM where data to be written to.
2083 //              uiNumBytes - Number of bytes to be written..
2084 //
2085 // Returns:
2086 //              OSAL_STATUS_SUCCESS - if NVM write is successfull.
2087 //              <FAILURE>                       - if failed.
2088 //-----------------------------------------------------------------------------
2089
2090 INT BeceemNVMWrite(
2091         PMINI_ADAPTER Adapter,
2092         PUINT pBuffer,
2093         UINT uiOffset,
2094         UINT uiNumBytes,
2095         BOOLEAN bVerify)
2096 {
2097         INT Status = 0;
2098         UINT uiTemp = 0;
2099         UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
2100         UINT uiIndex = 0;
2101 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2102         UINT value;
2103 #endif
2104         UINT uiFlashOffset = 0;
2105
2106         if(Adapter->eNVMType == NVM_FLASH)
2107         {
2108                 if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
2109                         Status = vendorextnWriteSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes,bVerify);
2110                 else
2111                 {
2112                         uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;
2113
2114 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
2115                         Status = bcmflash_raw_write((uiFlashOffset/FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer,uiNumBytes);
2116 #else
2117                         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2118                         value = 0;
2119                         wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2120
2121                         if(Adapter->bStatusWrite == TRUE)
2122                         {
2123                                 Status = BeceemFlashBulkWriteStatus(Adapter,
2124                                                         pBuffer,
2125                                                         uiFlashOffset,
2126                                                         uiNumBytes ,
2127                                                         bVerify);
2128                         }
2129                         else
2130                         {
2131
2132                                 Status = BeceemFlashBulkWrite(Adapter,
2133                                                         pBuffer,
2134                                                         uiFlashOffset,
2135                                                         uiNumBytes,
2136                                                         bVerify);
2137                         }
2138 #endif
2139                 }
2140
2141
2142                 if(uiOffset >= EEPROM_CALPARAM_START)
2143                 {
2144                         uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
2145                         while(uiNumBytes)
2146                         {
2147                                 if(uiNumBytes > BUFFER_4K)
2148                                 {
2149                                         wrm(Adapter,(uiMemoryLoc+uiIndex),(PCHAR)(pBuffer+(uiIndex/4)),BUFFER_4K);
2150                                         uiNumBytes -= BUFFER_4K;
2151                                         uiIndex += BUFFER_4K;
2152                                 }
2153                                 else
2154                                 {
2155                                         wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)(pBuffer+(uiIndex/4)),uiNumBytes);
2156                                         uiNumBytes = 0;
2157                                         break;
2158                                 }
2159                         }
2160                 }
2161                 else
2162                 {
2163                         if((uiOffset+uiNumBytes) > EEPROM_CALPARAM_START)
2164                         {
2165                                 ULONG ulBytesTobeSkipped = 0;
2166                                 PUCHAR pcBuffer = (PUCHAR)pBuffer;// char pointer to take care of odd byte cases.
2167                                 uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
2168                                 ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
2169                                 uiOffset += (EEPROM_CALPARAM_START - uiOffset);
2170                                 while(uiNumBytes)
2171                                 {
2172                                         if(uiNumBytes > BUFFER_4K)
2173                                         {
2174                                                 wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR )&pcBuffer[ulBytesTobeSkipped+uiIndex],BUFFER_4K);
2175                                                 uiNumBytes -= BUFFER_4K;
2176                                                 uiIndex += BUFFER_4K;
2177                                         }
2178                                         else
2179                                         {
2180                                                 wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)&pcBuffer[ulBytesTobeSkipped+uiIndex],uiNumBytes);
2181                                                 uiNumBytes = 0;
2182                                                 break;
2183                                         }
2184                                 }
2185
2186                         }
2187                 }
2188
2189         // restore the values.
2190                 wrmalt(Adapter,0x0f000C80,&uiTemp, sizeof(uiTemp));
2191         }
2192         else if(Adapter->eNVMType == NVM_EEPROM)
2193         {
2194                 Status = BeceemEEPROMBulkWrite(Adapter,
2195                                         (PUCHAR)pBuffer,
2196                                         uiOffset,
2197                                         uiNumBytes,
2198                                         bVerify);
2199                 if(bVerify)
2200                 {
2201                         Status = BeceemEEPROMReadBackandVerify(Adapter,(PUINT)pBuffer,uiOffset,uiNumBytes);
2202                 }
2203         }
2204         else
2205         {
2206                 Status = -1;
2207         }
2208         return Status;
2209 }
2210
2211 //-----------------------------------------------------------------------------
2212 // Procedure:   BcmUpdateSectorSize
2213 //
2214 // Description: Updates the sector size to FLASH.
2215 //
2216 // Arguments:
2217 //              Adapter       - ptr to Adapter object instance
2218 //          uiSectorSize - sector size
2219 //
2220 // Returns:
2221 //              OSAL_STATUS_SUCCESS - if NVM write is successfull.
2222 //              <FAILURE>                       - if failed.
2223 //-----------------------------------------------------------------------------
2224
2225 INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize)
2226 {
2227         INT Status = -1;
2228         FLASH_CS_INFO sFlashCsInfo = {0};
2229         UINT uiTemp = 0;
2230
2231         UINT uiSectorSig = 0;
2232         UINT uiCurrentSectorSize = 0;
2233
2234         UINT value;
2235
2236
2237
2238         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2239         value = 0;
2240         wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
2241
2242 //
2243 // Before updating the sector size in the reserved area, check if already present.
2244 //
2245         BeceemFlashBulkRead(Adapter,(PUINT)&sFlashCsInfo,Adapter->ulFlashControlSectionStart,sizeof(sFlashCsInfo));
2246         uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
2247         uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);
2248
2249         if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
2250         {
2251
2252                 if((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE))
2253                 {
2254                         if(uiSectorSize == uiCurrentSectorSize)
2255                         {
2256                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Provided sector size is same as programmed in Flash");
2257                                 Status = STATUS_SUCCESS;
2258                                 goto Restore ;
2259                         }
2260                 }
2261         }
2262
2263         if((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE))
2264         {
2265
2266                 sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize);
2267                 sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG);
2268
2269                 Status = BeceemFlashBulkWrite(Adapter,
2270                                         (PUINT)&sFlashCsInfo,
2271                                         Adapter->ulFlashControlSectionStart,
2272                                         sizeof(sFlashCsInfo),
2273                                         TRUE);
2274
2275
2276         }
2277
2278         Restore :
2279         // restore the values.
2280         wrmalt(Adapter, 0x0f000C80,&uiTemp, sizeof(uiTemp));
2281
2282
2283         return Status;
2284
2285 }
2286
2287 //-----------------------------------------------------------------------------
2288 // Procedure:   BcmGetFlashSectorSize
2289 //
2290 // Description: Finds the sector size of the FLASH.
2291 //
2292 // Arguments:
2293 //              Adapter    - ptr to Adapter object instance
2294 //
2295 // Returns:
2296 //              UINT - sector size.
2297 //
2298 //-----------------------------------------------------------------------------
2299
2300 static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize)
2301 {
2302         UINT uiSectorSize = 0;
2303         UINT uiSectorSig = 0;
2304
2305         if(Adapter->bSectorSizeOverride &&
2306                 (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2307                 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE))
2308         {
2309                 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2310         }
2311         else
2312         {
2313
2314                 uiSectorSig = FlashSectorSizeSig;
2315
2316                 if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
2317                 {
2318                         uiSectorSize = FlashSectorSize;
2319         //
2320         // If the sector size stored in the FLASH makes sense then use it.
2321         //
2322                         if(uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE)
2323                         {
2324                                 Adapter->uiSectorSize = uiSectorSize;
2325                         }
2326         //No valid size in FLASH, check if Config file has it.
2327                         else if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2328                                         Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
2329                         {
2330                                 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2331                         }
2332         // Init to Default, if none of the above works.
2333                         else
2334                         {
2335                                 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2336                         }
2337
2338                 }
2339                 else
2340                 {
2341                         if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2342                                         Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
2343                         {
2344                                 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2345                         }
2346                         else
2347                         {
2348                                 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2349                         }
2350                 }
2351         }
2352
2353         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size  :%x \n", Adapter->uiSectorSize);
2354         return Adapter->uiSectorSize;
2355 }
2356
2357 //-----------------------------------------------------------------------------
2358 // Procedure:   BcmInitEEPROMQueues
2359 //
2360 // Description: Initialization of EEPROM queues.
2361 //
2362 // Arguments:
2363 //              Adapter    - ptr to Adapter object instance
2364 //
2365 // Returns:
2366 //              <OSAL_STATUS_CODE>
2367 //-----------------------------------------------------------------------------
2368
2369 static INT BcmInitEEPROMQueues(PMINI_ADAPTER Adapter)
2370 {
2371         UINT value = 0;
2372         /* CHIP Bug : Clear the Avail bits on the Read queue. The default
2373          * value on this register is supposed to be 0x00001102.
2374          * But we get 0x00001122. */
2375         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Fixing reset value on 0x0f003004 register\n" );
2376         value = EEPROM_READ_DATA_AVAIL;
2377         wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
2378
2379         /* Flush the all the EEPROM queues. */
2380         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n");
2381         value =EEPROM_ALL_QUEUE_FLUSH ;
2382         wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
2383
2384         value = 0;
2385         wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
2386
2387         /* Read the EEPROM Status Register. Just to see, no real purpose. */
2388         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter) );
2389
2390         return STATUS_SUCCESS;
2391 } /* BcmInitEEPROMQueues() */
2392
2393 //-----------------------------------------------------------------------------
2394 // Procedure:   BcmInitNVM
2395 //
2396 // Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc.
2397 //
2398 // Arguments:
2399 //              Adapter    - ptr to Adapter object instance
2400 //
2401 // Returns:
2402 //              <OSAL_STATUS_CODE>
2403 //-----------------------------------------------------------------------------
2404
2405 INT BcmInitNVM(PMINI_ADAPTER ps_adapter)
2406 {
2407         BcmValidateNvmType(ps_adapter);
2408         BcmInitEEPROMQueues(ps_adapter);
2409
2410         if(ps_adapter->eNVMType == NVM_AUTODETECT)
2411         {
2412                 ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
2413                 if(ps_adapter->eNVMType == NVM_UNKNOWN)
2414                 {
2415                         BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
2416                 }
2417         }
2418         else if(ps_adapter->eNVMType == NVM_FLASH)
2419         {
2420                 BcmGetFlashCSInfo(ps_adapter);
2421         }
2422
2423         BcmGetNvmSize(ps_adapter);
2424
2425         return STATUS_SUCCESS;
2426 }
2427 /***************************************************************************/
2428 /*BcmGetNvmSize : set the EEPROM or flash size in Adapter.
2429 *
2430 *Input Parameter:
2431 *               Adapter data structure
2432 *Return Value :
2433 *               0. means sucess;
2434 */
2435 /***************************************************************************/
2436
2437 static INT BcmGetNvmSize(PMINI_ADAPTER Adapter)
2438 {
2439         if(Adapter->eNVMType == NVM_EEPROM)
2440         {
2441                 Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
2442         }
2443         else if(Adapter->eNVMType == NVM_FLASH)
2444         {
2445                 Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
2446         }
2447         return 0;
2448 }
2449
2450 //-----------------------------------------------------------------------------
2451 // Procedure:   BcmValidateNvm
2452 //
2453 // Description: Validates the NVM Type option selected against the device
2454 //
2455 // Arguments:
2456 //              Adapter    - ptr to Adapter object instance
2457 //
2458 // Returns:
2459 //              <VOID>
2460 //-----------------------------------------------------------------------------
2461 static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter)
2462 {
2463
2464         //
2465         // if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
2466         // Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
2467         // So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
2468         //
2469
2470         if(Adapter->eNVMType == NVM_FLASH &&
2471                 Adapter->chip_id < 0xBECE3300)
2472         {
2473                 Adapter->eNVMType = NVM_AUTODETECT;
2474         }
2475 }
2476 //-----------------------------------------------------------------------------
2477 // Procedure:   BcmReadFlashRDID
2478 //
2479 // Description: Reads ID from Serial Flash
2480 //
2481 // Arguments:
2482 //              Adapter    - ptr to Adapter object instance
2483 //
2484 // Returns:
2485 //              Flash ID
2486 //-----------------------------------------------------------------------------
2487 static ULONG BcmReadFlashRDID(PMINI_ADAPTER Adapter)
2488 {
2489         ULONG ulRDID = 0;
2490         UINT value;
2491 //
2492 // Read ID Instruction.
2493 //
2494         value = (FLASH_CMD_READ_ID<<24);
2495         wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value));
2496
2497 //Delay
2498         udelay(10);
2499 //
2500 // Read SPI READQ REG. The output will be WWXXYYZZ.
2501 // The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
2502 //
2503         rdmalt(Adapter, FLASH_SPI_READQ_REG,(PUINT)&ulRDID, sizeof(ulRDID));
2504
2505         return (ulRDID >>8);
2506
2507
2508 }
2509
2510 INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
2511 {
2512         if(psAdapter == NULL)
2513         {
2514                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
2515                 return -EINVAL;
2516         }
2517         psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL);
2518         if(psAdapter->psFlashCSInfo == NULL)
2519         {
2520                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 1.x");
2521                 return -ENOMEM;
2522         }
2523
2524         psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL);
2525         if(psAdapter->psFlash2xCSInfo == NULL)
2526         {
2527                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x");
2528                 kfree(psAdapter->psFlashCSInfo);
2529                 return -ENOMEM;
2530         }
2531
2532         psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL);
2533         if(psAdapter->psFlash2xVendorInfo == NULL)
2534         {
2535                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x");
2536                 kfree(psAdapter->psFlashCSInfo);
2537                 kfree(psAdapter->psFlash2xCSInfo);
2538                 return -ENOMEM;
2539         }
2540
2541         return STATUS_SUCCESS;
2542 }
2543
2544 INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
2545 {
2546         if(psAdapter == NULL)
2547         {
2548                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL");
2549                 return -EINVAL;
2550         }
2551         kfree(psAdapter->psFlashCSInfo);
2552         kfree(psAdapter->psFlash2xCSInfo);
2553         kfree(psAdapter->psFlash2xVendorInfo);
2554         return STATUS_SUCCESS ;
2555 }
2556
2557 static INT      BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,PMINI_ADAPTER Adapter)
2558 {
2559         UINT Index = 0;
2560     BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
2561         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is  :%x", (psFlash2xCSInfo->MagicNumber));
2562         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2563         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2564         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
2565         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
2566         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
2567         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
2568         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware  :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware ));
2569         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
2570         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
2571         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
2572         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
2573         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
2574         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
2575         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
2576         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
2577         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
2578         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
2579         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
2580         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
2581         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
2582         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
2583         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
2584         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
2585         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
2586         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
2587         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
2588         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
2589         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
2590         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
2591         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
2592         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
2593         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End  :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
2594         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
2595         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
2596         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
2597         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
2598         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
2599         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
2600         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
2601         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
2602         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
2603         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
2604         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
2605         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
2606         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
2607         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
2608         for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
2609         {
2610                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
2611                                 (psFlash2xCSInfo->SectorAccessBitMap[Index]));
2612         }
2613
2614         return STATUS_SUCCESS;
2615 }
2616
2617
2618 static INT      ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo)
2619 {
2620         UINT Index = 0;
2621         psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
2622         psFlash2xCSInfo->FlashLayoutVersion= ntohl(psFlash2xCSInfo->FlashLayoutVersion);
2623         //psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion);
2624         psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
2625         psFlash2xCSInfo->SCSIFirmwareVersion =ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
2626         psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
2627         psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
2628         psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware );
2629         psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
2630         psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
2631         psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
2632         psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
2633         psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
2634         psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
2635         psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
2636         psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
2637         psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
2638         psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
2639         psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
2640         psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
2641         psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
2642         psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
2643         psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
2644         psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
2645         psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
2646         psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
2647         psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
2648         psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
2649         psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
2650         psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
2651         psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
2652         psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
2653         psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
2654         psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
2655         psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
2656         psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
2657         psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
2658         psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
2659         psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
2660         psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
2661         psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
2662         psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
2663         psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
2664         psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
2665         psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
2666         psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
2667         for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
2668         {
2669                         psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
2670         }
2671         return STATUS_SUCCESS;
2672 }
2673
2674 static INT      ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo)
2675 {
2676         //UINT Index = 0;
2677         psFlashCSInfo->MagicNumber                                                      =ntohl(psFlashCSInfo->MagicNumber);
2678         psFlashCSInfo->FlashLayoutVersion                                       =ntohl(psFlashCSInfo->FlashLayoutVersion);
2679         psFlashCSInfo->ISOImageVersion                                          = ntohl(psFlashCSInfo->ISOImageVersion);
2680         //won't convert according to old assumption
2681         psFlashCSInfo->SCSIFirmwareVersion =(psFlashCSInfo->SCSIFirmwareVersion);
2682
2683         psFlashCSInfo->OffsetFromZeroForPart1ISOImage           = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
2684         psFlashCSInfo->OffsetFromZeroForScsiFirmware        = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
2685         psFlashCSInfo->SizeOfScsiFirmware                   = ntohl(psFlashCSInfo->SizeOfScsiFirmware );
2686         psFlashCSInfo->OffsetFromZeroForPart2ISOImage       = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
2687         psFlashCSInfo->OffsetFromZeroForCalibrationStart    = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2688         psFlashCSInfo->OffsetFromZeroForCalibrationEnd      = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
2689         psFlashCSInfo->OffsetFromZeroForVSAStart            = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
2690         psFlashCSInfo->OffsetFromZeroForVSAEnd              = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
2691         psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
2692         psFlashCSInfo->OffsetFromZeroForControlSectionData  = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
2693         psFlashCSInfo->CDLessInactivityTimeout                          = ntohl(psFlashCSInfo->CDLessInactivityTimeout);
2694         psFlashCSInfo->NewImageSignature                    = ntohl(psFlashCSInfo->NewImageSignature);
2695         psFlashCSInfo->FlashSectorSizeSig                   = ntohl(psFlashCSInfo->FlashSectorSizeSig);
2696         psFlashCSInfo->FlashSectorSize                      = ntohl(psFlashCSInfo->FlashSectorSize);
2697         psFlashCSInfo->FlashWriteSupportSize                = ntohl(psFlashCSInfo->FlashWriteSupportSize);
2698         psFlashCSInfo->TotalFlashSize                                   = ntohl(psFlashCSInfo->TotalFlashSize);
2699         psFlashCSInfo->FlashBaseAddr                                    = ntohl(psFlashCSInfo->FlashBaseAddr);
2700         psFlashCSInfo->FlashPartMaxSize                                 = ntohl(psFlashCSInfo->FlashPartMaxSize);
2701         psFlashCSInfo->IsCDLessDeviceBootSig                            = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
2702         psFlashCSInfo->MassStorageTimeout                               = ntohl(psFlashCSInfo->MassStorageTimeout);
2703
2704         return STATUS_SUCCESS;
2705 }
2706
2707 static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
2708 {
2709         return ( Adapter->uiVendorExtnFlag &&
2710                 (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
2711                 (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS) );
2712 }
2713
2714 static VOID UpdateVendorInfo(PMINI_ADAPTER Adapter)
2715 {
2716         B_UINT32 i = 0;
2717         UINT uiSizeSection = 0;
2718
2719         Adapter->uiVendorExtnFlag = FALSE;
2720
2721         for(i = 0;i < TOTAL_SECTIONS;i++)
2722                 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
2723
2724         if(STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
2725                 return;
2726
2727         i = 0;
2728         while(i < TOTAL_SECTIONS)
2729         {
2730                 if(!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT))
2731                 {
2732                         i++;
2733                         continue;
2734                 }
2735
2736                 Adapter->uiVendorExtnFlag = TRUE;
2737                 uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
2738                                                 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
2739
2740                 switch(i)
2741                 {
2742                 case DSD0:
2743                         if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
2744                         (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2745                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
2746                         else
2747                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
2748                         break;
2749
2750                 case DSD1:
2751                         if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
2752                         (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2753                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
2754                         else
2755                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
2756                         break;
2757
2758                 case DSD2:
2759                         if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
2760                         (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2761                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
2762                         else
2763                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
2764                         break;
2765                 case VSA0:
2766                         if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2767                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
2768                         else
2769                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
2770                         break;
2771
2772                 case VSA1:
2773                         if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2774                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
2775                         else
2776                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
2777                         break;
2778                 case VSA2:
2779                         if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2780                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
2781                         else
2782                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
2783                         break;
2784
2785                 default:
2786                         break;
2787                 }
2788                 i++;
2789         }
2790
2791 }
2792
2793 //-----------------------------------------------------------------------------
2794 // Procedure:   BcmGetFlashCSInfo
2795 //
2796 // Description: Reads control structure and gets Cal section addresses.
2797 //
2798 // Arguments:
2799 //              Adapter    - ptr to Adapter object instance
2800 //
2801 // Returns:
2802 //              <VOID>
2803 //-----------------------------------------------------------------------------
2804
2805 static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter)
2806 {
2807         //FLASH_CS_INFO sFlashCsInfo = {0};
2808
2809 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2810         UINT value;
2811 #endif
2812         UINT uiFlashLayoutMajorVersion;
2813         Adapter->uiFlashLayoutMinorVersion = 0;
2814         Adapter->uiFlashLayoutMajorVersion = 0;
2815         Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
2816
2817
2818         Adapter->uiFlashBaseAdd = 0;
2819         Adapter->ulFlashCalStart = 0;
2820         memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO));
2821         memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO));
2822
2823         if(!Adapter->bDDRInitDone)
2824         {
2825                 {
2826                         value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
2827                         wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
2828                 }
2829         }
2830
2831
2832         // Reading first 8 Bytes to get the Flash Layout
2833         // MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
2834         BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,8);
2835
2836         Adapter->psFlashCSInfo->FlashLayoutVersion =  ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
2837         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
2838         //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion));
2839         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is  :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));
2840
2841         if(FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber))
2842         {
2843                 uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2844                 Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2845         }
2846         else
2847         {
2848                 Adapter->uiFlashLayoutMinorVersion = 0;
2849                 uiFlashLayoutMajorVersion = 0;
2850         }
2851
2852         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);
2853
2854         if(uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER)
2855         {
2856                 BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,sizeof(FLASH_CS_INFO));
2857                 ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
2858                 Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2859
2860                 if(!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
2861                 {
2862                         Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
2863                 }
2864
2865                 if((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) &&
2866                    (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) &&
2867                    (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) &&
2868                    (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize)))
2869                 {
2870                         Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
2871                         Adapter->fpFlashWrite = flashByteWrite;
2872                         Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2873                 }
2874                 else
2875                 {
2876                         Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2877                         Adapter->fpFlashWrite = flashWrite;
2878                         Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2879                 }
2880
2881                 BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
2882                                          (Adapter->psFlashCSInfo->FlashSectorSize));
2883
2884
2885                 Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2886
2887
2888         }
2889         else
2890         {
2891                 if(BcmFlash2xBulkRead(Adapter,(PUINT)Adapter->psFlash2xCSInfo,NO_SECTION_VAL,
2892                                 Adapter->ulFlashControlSectionStart,sizeof(FLASH2X_CS_INFO)))
2893                 {
2894                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure \n");
2895                         return STATUS_FAILURE;
2896                 }
2897                 ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
2898                 BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter);
2899                 if((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
2900                    (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
2901                    (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
2902                    (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize))
2903                 {
2904                         Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
2905                         Adapter->fpFlashWrite = flashByteWrite;
2906                         Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2907                 }
2908                 else
2909                 {
2910                         Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2911                         Adapter->fpFlashWrite = flashWrite;
2912                         Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2913                 }
2914
2915                 BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
2916                                         Adapter->psFlash2xCSInfo->FlashSectorSize);
2917
2918                 UpdateVendorInfo(Adapter);
2919
2920                 BcmGetActiveDSD(Adapter);
2921                 BcmGetActiveISO(Adapter);
2922                 Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2923                 Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;
2924
2925         }
2926         /*
2927         Concerns: what if CS sector size does not match with this sector size ???
2928         what is the indication of AccessBitMap  in CS in flash 2.x ????
2929         */
2930         Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
2931
2932         Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
2933
2934
2935         return STATUS_SUCCESS ;
2936 }
2937
2938
2939 //-----------------------------------------------------------------------------
2940 // Procedure:   BcmGetNvmType
2941 //
2942 // Description: Finds the type of NVM used.
2943 //
2944 // Arguments:
2945 //              Adapter    - ptr to Adapter object instance
2946 //
2947 // Returns:
2948 //              NVM_TYPE
2949 //
2950 //-----------------------------------------------------------------------------
2951
2952 static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter)
2953 {
2954         UINT uiData = 0;
2955
2956         BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
2957         if(uiData == BECM)
2958         {
2959                 return NVM_EEPROM;
2960         }
2961         //
2962         // Read control struct and get cal addresses before accessing the flash
2963         //
2964         BcmGetFlashCSInfo(Adapter);
2965
2966         BeceemFlashBulkRead(Adapter,&uiData,0x0 + Adapter->ulFlashCalStart,4);
2967         if(uiData == BECM)
2968         {
2969                 return NVM_FLASH;
2970         }
2971 //
2972 // even if there is no valid signature on EEPROM/FLASH find out if they really exist.
2973 // if exist select it.
2974 //
2975         if(BcmGetEEPROMSize(Adapter))
2976         {
2977                 return NVM_EEPROM;
2978         }
2979
2980 //TBD for Flash.
2981
2982
2983         return NVM_UNKNOWN;
2984 }
2985
2986 /**
2987 *       BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
2988 *       @Adapter : Drivers Private Data structure
2989 *       @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
2990 *
2991 *       Return value:-
2992 *       On success it return the start offset of the provided section val
2993 *       On Failure -returns STATUS_FAILURE
2994 **/
2995
2996 INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
2997 {
2998         /*
2999         *       Considering all the section for which end offset can be calculated or directly given
3000         *       in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
3001         *       endoffset can't be calculated or given in CS Stucture.
3002         */
3003
3004         INT SectStartOffset = 0 ;
3005
3006         SectStartOffset = INVALID_OFFSET ;
3007
3008         if(IsSectionExistInVendorInfo(Adapter,eFlashSectionVal))
3009         {
3010                 return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
3011         }
3012
3013         switch(eFlashSectionVal)
3014         {
3015                 case ISO_IMAGE1 :
3016                           if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
3017                                 (IsNonCDLessDevice(Adapter) == FALSE))
3018                                   SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3019                            break;
3020                 case ISO_IMAGE2 :
3021                                 if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
3022                                         (IsNonCDLessDevice(Adapter) == FALSE))
3023                                         SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
3024                           break;
3025                 case DSD0 :
3026                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
3027                                         SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
3028                                 break;
3029                 case DSD1 :
3030                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
3031                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
3032                                 break;
3033                 case DSD2 :
3034                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
3035                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
3036                                 break;
3037                 case VSA0 :
3038                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
3039                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
3040                                 break;
3041                 case VSA1 :
3042                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
3043                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
3044                                 break;
3045                 case VSA2 :
3046                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
3047                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
3048                                 break;
3049                 case SCSI :
3050                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
3051                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
3052                                 break;
3053                 case CONTROL_SECTION :
3054                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
3055                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
3056                                 break;
3057                 case ISO_IMAGE1_PART2 :
3058                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
3059                                          SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
3060                                  break;
3061                 case ISO_IMAGE1_PART3 :
3062                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
3063                                   SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3064                                 break;
3065                 case ISO_IMAGE2_PART2 :
3066                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
3067                                          SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
3068                             break;
3069                 case ISO_IMAGE2_PART3 :
3070                           if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
3071                                   SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3072                           break;
3073                 default :
3074                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
3075                         SectStartOffset =  INVALID_OFFSET;
3076         }
3077         return SectStartOffset;
3078 }
3079
3080 /**
3081 *       BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
3082 *       @Adapter : Drivers Private Data structure
3083 *       @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
3084 *
3085 *       Return value:-
3086 *       On success it return the end offset of the provided section val
3087 *       On Failure -returns STATUS_FAILURE
3088 **/
3089
3090 INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
3091 {
3092         INT SectEndOffset = 0 ;
3093         SectEndOffset = INVALID_OFFSET;
3094
3095         if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
3096         {
3097                 return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
3098         }
3099
3100         switch(eFlash2xSectionVal)
3101         {
3102                 case ISO_IMAGE1 :
3103                          if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End!= UNINIT_PTR_IN_CS) &&
3104                                  (IsNonCDLessDevice(Adapter) == FALSE))
3105                                   SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
3106                            break;
3107                 case ISO_IMAGE2 :
3108                         if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End!= UNINIT_PTR_IN_CS) &&
3109                                 (IsNonCDLessDevice(Adapter) == FALSE))
3110                                         SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
3111                          break;
3112                 case DSD0 :
3113                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
3114                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
3115                         break;
3116                 case DSD1 :
3117                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
3118                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
3119                         break;
3120                 case DSD2 :
3121                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
3122                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
3123                         break;
3124                 case VSA0 :
3125                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
3126                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
3127                         break;
3128                 case VSA1 :
3129                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
3130                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
3131                         break;
3132                 case VSA2 :
3133                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
3134                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
3135                         break;
3136                 case SCSI :
3137                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
3138                                 SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
3139                                         (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
3140                         break;
3141                 case CONTROL_SECTION :
3142                                 //Not Clear So Putting failure. confirm and fix it.
3143                                 SectEndOffset = STATUS_FAILURE;
3144                 case ISO_IMAGE1_PART2 :
3145                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End!= UNINIT_PTR_IN_CS)
3146                                          SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
3147                                  break;
3148                 case ISO_IMAGE1_PART3 :
3149                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End!= UNINIT_PTR_IN_CS)
3150                                   SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
3151                                 break;
3152                 case ISO_IMAGE2_PART2 :
3153                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
3154                                          SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
3155                             break;
3156                 case ISO_IMAGE2_PART3 :
3157                           if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End!= UNINIT_PTR_IN_CS)
3158                                   SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
3159                           break;
3160
3161                 default :
3162                         SectEndOffset = INVALID_OFFSET;
3163         }
3164         return SectEndOffset ;
3165 }
3166
3167 /*
3168 *       BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
3169 *       @Adapter :Driver Private Data Structure
3170 *       @pBuffer : Buffer where data has to be put after reading
3171 *       @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
3172 *       @uiOffsetWithinSectionVal :- Offset with in provided section
3173 *       @uiNumBytes : Number of Bytes for Read
3174 *
3175 *       Return value:-
3176 *               return true on sucess and STATUS_FAILURE on fail.
3177 */
3178
3179 INT BcmFlash2xBulkRead(
3180         PMINI_ADAPTER Adapter,
3181         PUINT pBuffer,
3182         FLASH2X_SECTION_VAL eFlash2xSectionVal,
3183         UINT uiOffsetWithinSectionVal,
3184         UINT uiNumBytes)
3185 {
3186
3187         INT Status = STATUS_SUCCESS;
3188         INT SectionStartOffset = 0;
3189         UINT uiAbsoluteOffset = 0 ;
3190         UINT uiTemp =0, value =0 ;
3191         if(Adapter == NULL)
3192         {
3193                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
3194                 return -EINVAL;
3195         }
3196         if(Adapter->device_removed )
3197         {
3198                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
3199                 return -ENODEV;
3200         }
3201
3202         //NO_SECTION_VAL means absolute offset is given.
3203         if(eFlash2xSectionVal == NO_SECTION_VAL)
3204                 SectionStartOffset = 0;
3205         else
3206                 SectionStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
3207
3208         if(SectionStartOffset == STATUS_FAILURE )
3209         {
3210                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash 2.x Map ",eFlash2xSectionVal);
3211                 return -EINVAL;
3212         }
3213
3214         if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
3215                 return vendorextnReadSection(Adapter,(PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
3216
3217         //calculating  the absolute offset from FLASH;
3218         uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
3219         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3220         value = 0;
3221         wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
3222
3223         Status= BeceemFlashBulkRead(Adapter, pBuffer,uiAbsoluteOffset,uiNumBytes) ;
3224
3225         wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3226         if(Status)
3227         {
3228                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
3229                 return Status ;
3230         }
3231
3232         return Status;
3233 }
3234
3235 /*
3236 *       BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
3237 *       @Adapter :Driver Private Data Structure
3238 *       @pBuffer : Buffer From where data has to taken for writing
3239 *       @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
3240 *       @uiOffsetWithinSectionVal :- Offset with in provided section
3241 *       @uiNumBytes : Number of Bytes for Write
3242 *
3243 *       Return value:-
3244 *               return true on sucess and STATUS_FAILURE on fail.
3245 *
3246 */
3247
3248 INT BcmFlash2xBulkWrite(
3249         PMINI_ADAPTER Adapter,
3250         PUINT pBuffer,
3251         FLASH2X_SECTION_VAL eFlash2xSectVal,
3252         UINT uiOffset,
3253         UINT uiNumBytes,
3254         UINT bVerify)
3255 {
3256
3257         INT Status      = STATUS_SUCCESS;
3258         UINT FlashSectValStartOffset = 0;
3259         UINT uiTemp = 0, value = 0;
3260         if(Adapter == NULL)
3261         {
3262                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
3263                 return -EINVAL;
3264         }
3265         if(Adapter->device_removed )
3266         {
3267                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
3268                 return -ENODEV;
3269         }
3270
3271         //NO_SECTION_VAL means absolute offset is given.
3272         if(eFlash2xSectVal == NO_SECTION_VAL)
3273                 FlashSectValStartOffset = 0;
3274         else
3275                 FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectVal);
3276
3277         if(FlashSectValStartOffset == STATUS_FAILURE )
3278         {
3279                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash Map 2.x",eFlash2xSectVal);
3280                 return -EINVAL;
3281         }
3282
3283         if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectVal))
3284                 return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
3285
3286         //calculating  the absolute offset from FLASH;
3287         uiOffset = uiOffset + FlashSectValStartOffset;
3288
3289         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3290         value = 0;
3291         wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
3292
3293         Status = BeceemFlashBulkWrite(Adapter, pBuffer,uiOffset,uiNumBytes,bVerify);
3294
3295         wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3296         if(Status)
3297         {
3298                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
3299                 return Status ;
3300         }
3301
3302         return Status;
3303
3304 }
3305
3306 /**
3307 *       BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
3308 *       @Adapter :-Drivers private Data Structure
3309 *
3310 *       Return Value:-
3311 *               Return STATUS_SUCESS if get sucess in setting the right DSD else negaive error code
3312 *
3313 **/
3314 static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter)
3315 {
3316         FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
3317
3318         uiHighestPriDSD = getHighestPriDSD(Adapter);
3319         Adapter->eActiveDSD = uiHighestPriDSD;
3320
3321         if(DSD0  == uiHighestPriDSD)
3322                 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
3323         if(DSD1 == uiHighestPriDSD)
3324                 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
3325         if(DSD2 == uiHighestPriDSD)
3326                 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
3327         if(Adapter->eActiveDSD)
3328                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
3329         if(Adapter->eActiveDSD == 0)
3330         {
3331                 //if No DSD gets Active, Make Active the DSD with WR  permission
3332                 if(IsSectionWritable(Adapter,DSD2))
3333                 {
3334                         Adapter->eActiveDSD = DSD2;
3335                         Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
3336                 }
3337                 else if(IsSectionWritable(Adapter,DSD1))
3338                 {
3339                         Adapter->eActiveDSD = DSD1;
3340                         Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
3341                 }
3342                 else if(IsSectionWritable(Adapter,DSD0))
3343                 {
3344                         Adapter->eActiveDSD = DSD0;
3345                         Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
3346                 }
3347         }
3348
3349         return STATUS_SUCCESS;
3350 }
3351
3352
3353 /**
3354 *       BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
3355 *       @Adapter : Driver private Data Structure
3356 *
3357 *       Return Value:-
3358 *               Sucsess:- STATUS_SUCESS
3359 *               Failure- : negative erro code
3360 *
3361 **/
3362
3363 static INT BcmGetActiveISO(PMINI_ADAPTER Adapter)
3364 {
3365
3366         INT HighestPriISO = 0 ;
3367         HighestPriISO = getHighestPriISO(Adapter);
3368
3369         Adapter->eActiveISO = HighestPriISO ;
3370         if(Adapter->eActiveISO == ISO_IMAGE2)
3371                 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
3372         else if(Adapter->eActiveISO == ISO_IMAGE1)
3373                 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3374
3375         if(Adapter->eActiveISO)
3376                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Active ISO :%x", Adapter->eActiveISO);
3377
3378         return STATUS_SUCCESS;
3379 }
3380
3381 /**
3382 *       IsOffsetWritable :- it will tell the access permission of the sector having passed offset
3383 *       @Adapter : Drivers Private Data Structure
3384 *       @uiOffset : Offset provided in the Flash
3385 *
3386 *       Return Value:-
3387 *       Sucess:-TRUE ,  offset is writable
3388 *       Failure:-FALSE, offset is RO
3389 *
3390 **/
3391 B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset)
3392 {
3393         UINT uiSectorNum = 0;
3394         UINT uiWordOfSectorPermission =0;
3395         UINT uiBitofSectorePermission = 0;
3396         B_UINT32 permissionBits = 0;
3397         uiSectorNum = uiOffset/Adapter->uiSectorSize;
3398
3399         //calculating the word having this Sector Access permission from SectorAccessBitMap Array
3400         uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum /16];
3401
3402         //calculating the bit index inside the word for  this sector
3403         uiBitofSectorePermission = 2*(15 - uiSectorNum %16);
3404
3405         //Setting Access permission
3406         permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission) ;
3407         permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
3408         if(permissionBits == SECTOR_READWRITE_PERMISSION)
3409                 return  TRUE;
3410         else
3411                 return FALSE;
3412 }
3413
3414 static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
3415 {
3416     PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
3417         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
3418         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE1  :0X%x", psFlash2xBitMap->ISO_IMAGE1);
3419         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE2  :0X%x", psFlash2xBitMap->ISO_IMAGE2);
3420         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD0  :0X%x", psFlash2xBitMap->DSD0);
3421         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD1  :0X%x", psFlash2xBitMap->DSD1);
3422         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD2  :0X%x", psFlash2xBitMap->DSD2);
3423         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA0  :0X%x", psFlash2xBitMap->VSA0);
3424         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA1  :0X%x", psFlash2xBitMap->VSA1);
3425         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA2  :0X%x", psFlash2xBitMap->VSA2);
3426         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"SCSI  :0X%x", psFlash2xBitMap->SCSI);
3427         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"CONTROL_SECTION  :0X%x", psFlash2xBitMap->CONTROL_SECTION);
3428
3429         return STATUS_SUCCESS;
3430 }
3431
3432 /**
3433 *       BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
3434 *       8bit has been assigned to every section.
3435         bit[0] :Section present or not
3436         bit[1] :section is valid or not
3437         bit[2] : Secton is read only or has write permission too.
3438         bit[3] : Active Section -
3439         bit[7...4] = Reserved .
3440
3441         @Adapter:-Driver private Data Structure
3442 *
3443 *       Return value:-
3444 *       Sucess:- STATUS_SUCESS
3445 *       Failure:- negative error code
3446 **/
3447
3448 INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap)
3449 {
3450
3451
3452         PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
3453         FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
3454         FLASH2X_SECTION_VAL uiHighestPriISO= 0 ;
3455         BOOLEAN SetActiveDSDDone = FALSE ;
3456         BOOLEAN SetActiveISODone = FALSE ;
3457
3458         //For 1.x map all the section except DSD0 will be shown as not present
3459         //This part will be used by calibration tool to detect the number of DSD present in Flash.
3460         if(IsFlash2x(Adapter) == FALSE)
3461         {
3462                 psFlash2xBitMap->ISO_IMAGE2 = 0;
3463                 psFlash2xBitMap->ISO_IMAGE1 = 0;
3464                 psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF;   //0000(Reseved)1(Active)0(RW)1(valid)1(present)
3465                 psFlash2xBitMap->DSD1  = 0 ;
3466                 psFlash2xBitMap->DSD2 = 0 ;
3467                 psFlash2xBitMap->VSA0 = 0 ;
3468                 psFlash2xBitMap->VSA1 = 0 ;
3469                 psFlash2xBitMap->VSA2 = 0 ;
3470                 psFlash2xBitMap->CONTROL_SECTION = 0 ;
3471                 psFlash2xBitMap->SCSI= 0 ;
3472                 psFlash2xBitMap->Reserved0 = 0 ;
3473                 psFlash2xBitMap->Reserved1 = 0 ;
3474                 psFlash2xBitMap->Reserved2 = 0 ;
3475                 return STATUS_SUCCESS ;
3476
3477         }
3478
3479         uiHighestPriDSD = getHighestPriDSD(Adapter);
3480         uiHighestPriISO = getHighestPriISO(Adapter);
3481
3482         ///
3483         //      IS0 IMAGE 2
3484         ///
3485         if((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS)
3486         {
3487                 //Setting the 0th Bit representing the Section is present or not.
3488                 psFlash2xBitMap->ISO_IMAGE2= psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
3489
3490
3491                 if(ReadISOSignature(Adapter,ISO_IMAGE2)== ISO_IMAGE_MAGIC_NUMBER)
3492                         psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
3493
3494
3495                 //Calculation for extrating the Access permission
3496                 if(IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
3497                         psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
3498
3499                 if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2)
3500                 {
3501                         psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT ;
3502                         SetActiveISODone = TRUE;
3503                 }
3504
3505         }
3506
3507         ///
3508         //      IS0 IMAGE 1
3509         ///
3510         if((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS)
3511         {
3512                 //Setting the 0th Bit representing the Section is present or not.
3513                 psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
3514
3515                 if(ReadISOSignature(Adapter,ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
3516                         psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
3517
3518                 //      Calculation for extrating the Access permission
3519                 if(IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
3520                         psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
3521
3522                 if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1)
3523                 {
3524                         psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT ;
3525                         SetActiveISODone = TRUE;
3526                 }
3527         }
3528
3529
3530
3531         ///
3532         // DSD2
3533         ///
3534         if((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS)
3535         {
3536                 //Setting the 0th Bit representing the Section is present or not.
3537                 psFlash2xBitMap->DSD2= psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
3538
3539                 if(ReadDSDSignature(Adapter,DSD2)== DSD_IMAGE_MAGIC_NUMBER)
3540                         psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
3541
3542                 //Calculation for extrating the Access permission
3543                 if(IsSectionWritable(Adapter, DSD2) == FALSE)
3544                 {
3545                         psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
3546
3547                 }
3548                 else
3549                 {
3550                         //Means section is writable
3551                         if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2))
3552                         {
3553                                 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT ;
3554                                 SetActiveDSDDone =TRUE ;
3555                         }
3556                 }
3557         }
3558
3559         ///
3560         //      DSD 1
3561         ///
3562         if((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS)
3563         {
3564                 //Setting the 0th Bit representing the Section is present or not.
3565                 psFlash2xBitMap->DSD1= psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
3566
3567
3568                 if(ReadDSDSignature(Adapter,DSD1)== DSD_IMAGE_MAGIC_NUMBER)
3569                         psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
3570
3571                 //Calculation for extrating the Access permission
3572                 if(IsSectionWritable(Adapter, DSD1) == FALSE)
3573                 {
3574                         psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
3575                 }
3576                 else
3577                 {
3578                         //Means section is writable
3579                         if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1))
3580                         {
3581                                         psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT ;
3582                                         SetActiveDSDDone =TRUE ;
3583                         }
3584                 }
3585
3586         }
3587
3588         ///
3589         //For DSD 0
3590         //
3591         if((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS)
3592         {
3593                 //Setting the 0th Bit representing the Section is present or not.
3594                 psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
3595
3596                 if(ReadDSDSignature(Adapter,DSD0) == DSD_IMAGE_MAGIC_NUMBER)
3597                         psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
3598
3599                 //Setting Access permission
3600                 if(IsSectionWritable(Adapter, DSD0) == FALSE)
3601                 {
3602                         psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
3603                 }
3604                 else
3605                 {
3606                         //Means section is writable
3607                         if((SetActiveDSDDone == FALSE) &&(uiHighestPriDSD == DSD0))
3608                         {
3609                                         psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT ;
3610                                         SetActiveDSDDone =TRUE ;
3611                         }
3612                 }
3613         }
3614
3615         ///
3616         //      VSA 0
3617         ///
3618         if((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS)
3619         {
3620                 //Setting the 0th Bit representing the Section is present or not.
3621                 psFlash2xBitMap->VSA0= psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
3622
3623                 //Setting the Access Bit. Map is not defined hece setting it always valid
3624                 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
3625
3626                 //Calculation for extrating the Access permission
3627                 if(IsSectionWritable(Adapter, VSA0) == FALSE)
3628                         psFlash2xBitMap->VSA0 |=  FLASH2X_SECTION_RO;
3629
3630                 //By Default section is Active
3631                 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT ;
3632
3633         }
3634
3635
3636         ///
3637         //       VSA 1
3638         ///
3639
3640         if((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS)
3641         {
3642                 //Setting the 0th Bit representing the Section is present or not.
3643                 psFlash2xBitMap->VSA1= psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
3644
3645                 //Setting the Access Bit. Map is not defined hece setting it always valid
3646                 psFlash2xBitMap->VSA1|= FLASH2X_SECTION_VALID;
3647
3648                 //Checking For Access permission
3649                 if(IsSectionWritable(Adapter, VSA1) == FALSE)
3650                         psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
3651
3652                 //By Default section is Active
3653                 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT ;
3654
3655         }
3656
3657
3658         ///
3659         //      VSA 2
3660         ///
3661
3662         if((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS)
3663         {
3664                 //Setting the 0th Bit representing the Section is present or not.
3665                 psFlash2xBitMap->VSA2= psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
3666
3667
3668                 //Setting the Access Bit. Map is not defined hece setting it always valid
3669                 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
3670
3671                 //Checking For Access permission
3672                 if(IsSectionWritable(Adapter, VSA2) == FALSE)
3673                         psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
3674
3675                 //By Default section is Active
3676                 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT ;
3677         }
3678
3679         ///
3680         // SCSI Section
3681         ///
3682         if((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS)
3683         {
3684                 //Setting the 0th Bit representing the Section is present or not.
3685                 psFlash2xBitMap->SCSI= psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
3686
3687
3688                 //Setting the Access Bit. Map is not defined hece setting it always valid
3689                 psFlash2xBitMap->SCSI|= FLASH2X_SECTION_VALID;
3690
3691                 //Checking For Access permission
3692                 if(IsSectionWritable(Adapter, SCSI) == FALSE)
3693                         psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
3694
3695                 //By Default section is Active
3696                 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT ;
3697
3698         }
3699
3700
3701         ///
3702         //      Control Section
3703         ///
3704         if((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS)
3705         {
3706                 //Setting the 0th Bit representing the Section is present or not.
3707                 psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
3708
3709
3710                 //Setting the Access Bit. Map is not defined hece setting it always valid
3711                 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
3712
3713                 //Checking For Access permission
3714                 if(IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
3715                         psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
3716
3717                 //By Default section is Active
3718                 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT ;
3719
3720         }
3721
3722         ///
3723         //      For Reserved Sections
3724         ///
3725         psFlash2xBitMap->Reserved0 = 0;
3726         psFlash2xBitMap->Reserved0 = 0;
3727         psFlash2xBitMap->Reserved0 = 0;
3728
3729         BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
3730
3731         return STATUS_SUCCESS ;
3732
3733 }
3734 /**
3735 BcmSetActiveSection :- Set Active section is used to make priority field highest over other
3736                                         section of same type.
3737
3738 @Adapater :- Bcm Driver Private Data Structure
3739 @eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
3740
3741 Return Value:- Make the priorit highest else return erorr code
3742
3743 **/
3744 INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal)
3745 {
3746         unsigned int SectImagePriority = 0;
3747         INT Status =STATUS_SUCCESS;
3748
3749         //DSD_HEADER sDSD = {0};
3750         //ISO_HEADER sISO = {0};
3751         INT HighestPriDSD = 0 ;
3752         INT HighestPriISO = 0;
3753
3754
3755
3756         Status = IsSectionWritable(Adapter,eFlash2xSectVal) ;
3757         if(Status != TRUE )
3758         {
3759                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section <%d> is not writable",eFlash2xSectVal);
3760                 return STATUS_FAILURE;
3761         }
3762
3763         Adapter->bHeaderChangeAllowed = TRUE ;
3764         switch(eFlash2xSectVal)
3765         {
3766                 case ISO_IMAGE1 :
3767                 case ISO_IMAGE2 :
3768                         if(ReadISOSignature(Adapter,eFlash2xSectVal)== ISO_IMAGE_MAGIC_NUMBER )
3769                         {
3770                                 HighestPriISO = getHighestPriISO(Adapter);
3771
3772                                 if(HighestPriISO == eFlash2xSectVal     )
3773                                 {
3774                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already  has highest priority",eFlash2xSectVal );
3775                                         Status = STATUS_SUCCESS ;
3776                                         break;
3777                                 }
3778
3779                                 SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
3780
3781                                 if((SectImagePriority <= 0) && IsSectionWritable(Adapter,HighestPriISO))
3782                                 {
3783                                         // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
3784                                         // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
3785                                         // by user
3786                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
3787                                         SectImagePriority = htonl(0x1);
3788                                         Status = BcmFlash2xBulkWrite(Adapter,
3789                                                                 &SectImagePriority,
3790                                                                 HighestPriISO,
3791                                                                 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
3792                                                                 SIGNATURE_SIZE,
3793                                                                 TRUE);
3794
3795                                         if(Status)
3796                                         {
3797                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
3798                                                 Status = STATUS_FAILURE;
3799                                                 break ;
3800                                         }
3801
3802                                         HighestPriISO = getHighestPriISO(Adapter);
3803
3804                                         if(HighestPriISO == eFlash2xSectVal     )
3805                                         {
3806                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already  has highest priority",eFlash2xSectVal );
3807                                                 Status = STATUS_SUCCESS ;
3808                                                 break;
3809                                         }
3810
3811                                         SectImagePriority = 2;
3812                                  }
3813
3814
3815                                 SectImagePriority = htonl(SectImagePriority);
3816
3817                                 Status = BcmFlash2xBulkWrite(Adapter,
3818                                                                 &SectImagePriority,
3819                                                                 eFlash2xSectVal,
3820                                                                 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
3821                                                                 SIGNATURE_SIZE,
3822                                                                 TRUE);
3823                                 if(Status)
3824                                 {
3825                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
3826                                         break ;
3827                                 }
3828                         }
3829                         else
3830                         {
3831                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3832                                 Status = STATUS_FAILURE ;
3833                                 break;
3834                         }
3835                         break;
3836                 case DSD0 :
3837                 case DSD1 :
3838                 case DSD2 :
3839                         if(ReadDSDSignature(Adapter,eFlash2xSectVal)== DSD_IMAGE_MAGIC_NUMBER)
3840                         {
3841                                 HighestPriDSD = getHighestPriDSD(Adapter);
3842
3843                                 if((HighestPriDSD == eFlash2xSectVal))
3844                                 {
3845                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given DSD<%x> already  has highest priority", eFlash2xSectVal);
3846                                         Status = STATUS_SUCCESS ;
3847                                         break;
3848                                 }
3849
3850                                 SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1 ;
3851                                 if(SectImagePriority <= 0)
3852                                 {
3853                                         // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
3854                                         // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
3855                                         // by user
3856                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
3857                                         SectImagePriority = htonl(0x1);
3858
3859                                         Status = BcmFlash2xBulkWrite(Adapter,
3860                                                                         &SectImagePriority,
3861                                                                         HighestPriDSD,
3862                                                                         Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3863                                                                         SIGNATURE_SIZE,
3864                                                                         TRUE);
3865
3866                                         if(Status)
3867                                         {
3868                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3869                                                 break ;
3870                                         }
3871
3872                                         HighestPriDSD = getHighestPriDSD(Adapter);
3873
3874                                         if((HighestPriDSD == eFlash2xSectVal))
3875                                         {
3876                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
3877                                                 Status = STATUS_SUCCESS ;
3878                                                 break;
3879                                         }
3880
3881                                         SectImagePriority = htonl(0x2);
3882                                         Status = BcmFlash2xBulkWrite(Adapter,
3883                                                                         &SectImagePriority,
3884                                                                         HighestPriDSD,
3885                                                                         Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3886                                                                         SIGNATURE_SIZE,
3887                                                                         TRUE);
3888
3889                                         if(Status)
3890                                         {
3891                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3892                                                 break ;
3893                                         }
3894
3895                                         HighestPriDSD = getHighestPriDSD(Adapter);
3896
3897                                         if((HighestPriDSD == eFlash2xSectVal))
3898                                         {
3899                                                 Status = STATUS_SUCCESS ;
3900                                                 break;
3901                                         }
3902                                         SectImagePriority = 3 ;
3903
3904                                 }
3905                                 SectImagePriority = htonl(SectImagePriority);
3906                                 Status = BcmFlash2xBulkWrite(Adapter,
3907                                                                 &SectImagePriority,
3908                                                                 eFlash2xSectVal,
3909                                                                 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3910                                                                 SIGNATURE_SIZE ,
3911                                                                 TRUE);
3912                                 if(Status)
3913                                 {
3914                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
3915                                         Status = STATUS_FAILURE ;
3916                                         break ;
3917                                 }
3918                         }
3919                         else
3920                         {
3921                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3922                                 Status = STATUS_FAILURE ;
3923                                 break;
3924                         }
3925                         break;
3926                 case VSA0 :
3927                 case VSA1 :
3928                 case VSA2 :
3929                         //Has to be decided
3930                         break ;
3931                 default :
3932                                 Status = STATUS_FAILURE ;
3933                                 break;
3934
3935         }
3936
3937         Adapter->bHeaderChangeAllowed = FALSE ;
3938         return Status;
3939
3940 }
3941
3942 /**
3943 BcmCopyISO - Used only for copying the ISO section
3944 @Adapater :- Bcm Driver Private Data Structure
3945 @sCopySectStrut :- Section copy structure
3946
3947 Return value:- SUCCESS if copies successfully else negative error code
3948
3949 **/
3950 INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
3951 {
3952
3953         PCHAR Buff = NULL;
3954         FLASH2X_SECTION_VAL eISOReadPart = 0,eISOWritePart = 0;
3955         UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
3956         UINT uiTotalDataToCopy = 0;
3957         BOOLEAN IsThisHeaderSector = FALSE ;
3958         UINT sigOffset = 0;
3959         UINT ISOLength = 0;
3960         UINT Status = STATUS_SUCCESS;
3961         UINT SigBuff[MAX_RW_SIZE];
3962         UINT i = 0;
3963
3964         if(ReadISOSignature(Adapter,sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER)
3965         {
3966                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3967                 return STATUS_FAILURE;
3968         }
3969
3970         Status = BcmFlash2xBulkRead(Adapter,
3971                                            &ISOLength,
3972                                            sCopySectStrut.SrcSection,
3973                                            0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageSize),
3974                                            4);
3975
3976         if(Status)
3977         {
3978                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
3979                 return Status;
3980         }
3981
3982         ISOLength = htonl(ISOLength);
3983
3984         if(ISOLength % Adapter->uiSectorSize)
3985         {
3986                 ISOLength = Adapter->uiSectorSize*(1 + ISOLength/Adapter->uiSectorSize);
3987         }
3988
3989         sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);
3990
3991         Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
3992
3993         if(Buff == NULL)
3994         {
3995                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for section size");
3996                         return -ENOMEM;
3997         }
3998
3999         if(sCopySectStrut.SrcSection ==ISO_IMAGE1 && sCopySectStrut.DstSection ==ISO_IMAGE2)
4000         {
4001                 eISOReadPart = ISO_IMAGE1 ;
4002                 eISOWritePart = ISO_IMAGE2 ;
4003                 uiReadOffsetWithinPart =  0;
4004                 uiWriteOffsetWithinPart = 0 ;
4005
4006                 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
4007                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
4008                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
4009                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
4010                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
4011                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
4012
4013                 if(uiTotalDataToCopy < ISOLength)
4014                 {
4015                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
4016                         return STATUS_FAILURE;
4017                 }
4018
4019                 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
4020                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
4021                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
4022                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
4023                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
4024                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
4025
4026                 if(uiTotalDataToCopy < ISOLength)
4027                 {
4028                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
4029                         return STATUS_FAILURE;
4030                 }
4031
4032                 uiTotalDataToCopy = ISOLength;
4033
4034                 CorruptISOSig(Adapter,ISO_IMAGE2);
4035
4036                 while(uiTotalDataToCopy)
4037                 {
4038                         if(uiTotalDataToCopy == Adapter->uiSectorSize)
4039                         {
4040                                 //Setting for write of first sector. First sector is assumed to be written in last
4041                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
4042                                 eISOReadPart = ISO_IMAGE1 ;
4043                                 uiReadOffsetWithinPart = 0;
4044                                 eISOWritePart = ISO_IMAGE2;
4045                                 uiWriteOffsetWithinPart = 0 ;
4046                                 IsThisHeaderSector = TRUE ;
4047
4048                         }
4049                         else
4050                         {
4051                                 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
4052                                 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
4053
4054                                 if((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) ))
4055                                 {
4056                                         eISOReadPart = ISO_IMAGE1_PART2 ;
4057                                         uiReadOffsetWithinPart = 0;
4058                                 }
4059                                 if((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
4060                                 {
4061                                         eISOReadPart = ISO_IMAGE1_PART3 ;
4062                                         uiReadOffsetWithinPart = 0;
4063                                 }
4064                                 if((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)))
4065                                 {
4066                                         eISOWritePart = ISO_IMAGE2_PART2 ;
4067                                         uiWriteOffsetWithinPart = 0;
4068                                 }
4069                                 if((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
4070                                 {
4071                                         eISOWritePart = ISO_IMAGE2_PART3 ;
4072                                         uiWriteOffsetWithinPart = 0;
4073                                 }
4074                         }
4075
4076                         Status = BcmFlash2xBulkRead(Adapter,
4077                                                                    (PUINT)Buff,
4078                                                                    eISOReadPart,
4079                                                                    uiReadOffsetWithinPart,
4080                                                                    Adapter->uiSectorSize
4081                                                                 );
4082
4083                         if(Status)
4084                         {
4085                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
4086                                 break;
4087                         }
4088
4089                         if(IsThisHeaderSector == TRUE)
4090                         {
4091                                 //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
4092                                 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
4093
4094                                 for(i = 0; i < MAX_RW_SIZE;i++)
4095                                         *(Buff + sigOffset + i) = 0xFF;
4096                         }
4097                         Adapter->bHeaderChangeAllowed = TRUE ;
4098
4099                         Status = BcmFlash2xBulkWrite(Adapter,
4100                                                                  (PUINT)Buff,
4101                                                                  eISOWritePart,
4102                                                                  uiWriteOffsetWithinPart,
4103                                                                  Adapter->uiSectorSize,
4104                                                                  TRUE);
4105                         if(Status)
4106                         {
4107                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
4108                                 break;
4109                         }
4110
4111                         Adapter->bHeaderChangeAllowed = FALSE;
4112
4113                         if(IsThisHeaderSector == TRUE)
4114                         {
4115                                 WriteToFlashWithoutSectorErase(Adapter,
4116                                                                                                 SigBuff,
4117                                                                                                 eISOWritePart,
4118                                                                                                 sigOffset,
4119                                                                                                 MAX_RW_SIZE);
4120                                 IsThisHeaderSector = FALSE ;
4121                         }
4122                         //substracting the written Data
4123                         uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
4124                 }
4125
4126
4127         }
4128
4129         if(sCopySectStrut.SrcSection ==ISO_IMAGE2 && sCopySectStrut.DstSection ==ISO_IMAGE1)
4130         {
4131                 eISOReadPart = ISO_IMAGE2 ;
4132                 eISOWritePart = ISO_IMAGE1 ;
4133                 uiReadOffsetWithinPart =        0;
4134                 uiWriteOffsetWithinPart = 0 ;
4135
4136                 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
4137                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
4138                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
4139                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
4140                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
4141                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
4142
4143                 if(uiTotalDataToCopy < ISOLength)
4144                 {
4145                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
4146                         return STATUS_FAILURE;
4147                 }
4148
4149                 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
4150                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
4151                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
4152                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
4153                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
4154                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
4155
4156                 if(uiTotalDataToCopy < ISOLength)
4157                 {
4158                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
4159                         return STATUS_FAILURE;
4160                 }
4161
4162                 uiTotalDataToCopy = ISOLength;
4163
4164                 CorruptISOSig(Adapter,ISO_IMAGE1);
4165
4166                 while(uiTotalDataToCopy)
4167                 {
4168                         if(uiTotalDataToCopy == Adapter->uiSectorSize)
4169                         {
4170                                 //Setting for write of first sector. First sector is assumed to be written in last
4171                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
4172                                 eISOReadPart = ISO_IMAGE2 ;
4173                                 uiReadOffsetWithinPart = 0;
4174                                 eISOWritePart = ISO_IMAGE1;
4175                                 uiWriteOffsetWithinPart = 0 ;
4176                                 IsThisHeaderSector = TRUE;
4177
4178                         }
4179                         else
4180                         {
4181                                 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
4182                                 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
4183
4184                                 if((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) ))
4185                                 {
4186                                         eISOReadPart = ISO_IMAGE2_PART2 ;
4187                                         uiReadOffsetWithinPart = 0;
4188                                 }
4189                                 if((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
4190                                 {
4191                                         eISOReadPart = ISO_IMAGE2_PART3 ;
4192                                         uiReadOffsetWithinPart = 0;
4193                                 }
4194                                 if((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)))
4195                                 {
4196                                         eISOWritePart = ISO_IMAGE1_PART2 ;
4197                                         uiWriteOffsetWithinPart = 0;
4198                                 }
4199                                 if((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
4200                                 {
4201                                         eISOWritePart = ISO_IMAGE1_PART3 ;
4202                                         uiWriteOffsetWithinPart = 0;
4203                                 }
4204                         }
4205
4206                         Status = BcmFlash2xBulkRead(Adapter,
4207                                                                    (PUINT)Buff,
4208                                                                    eISOReadPart,
4209                                                                    uiReadOffsetWithinPart,
4210                                                                    Adapter->uiSectorSize
4211                                                                 );
4212                         if(Status)
4213                         {
4214                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
4215                                 break;
4216                         }
4217
4218                         if(IsThisHeaderSector == TRUE)
4219                         {
4220                                 //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
4221                                 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
4222
4223                                 for(i = 0; i < MAX_RW_SIZE;i++)
4224                                         *(Buff + sigOffset + i) = 0xFF;
4225
4226                         }
4227                         Adapter->bHeaderChangeAllowed = TRUE ;
4228                         Status = BcmFlash2xBulkWrite(Adapter,
4229                                                                  (PUINT)Buff,
4230                                                                  eISOWritePart,
4231                                                                  uiWriteOffsetWithinPart,
4232                                                                  Adapter->uiSectorSize,
4233                                                                  TRUE);
4234
4235                         if(Status)
4236                         {
4237                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
4238                                 break;
4239                         }
4240
4241                         Adapter->bHeaderChangeAllowed = FALSE ;
4242
4243                         if(IsThisHeaderSector == TRUE)
4244                         {
4245                                 WriteToFlashWithoutSectorErase(Adapter,
4246                                                                                                 SigBuff,
4247                                                                                                 eISOWritePart,
4248                                                                                                 sigOffset,
4249                                                                                                 MAX_RW_SIZE);
4250                                 IsThisHeaderSector = FALSE ;
4251                         }
4252
4253                         //substracting the written Data
4254                         uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
4255                 }
4256
4257
4258         }
4259
4260         kfree(Buff);
4261
4262         return Status;
4263 }
4264 /**
4265 BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
4266                                              It will corrupt the sig, if Section is writable, by making first bytes as zero.
4267 @Adapater :- Bcm Driver Private Data Structure
4268 @eFlash2xSectionVal :- Flash section val which has header
4269
4270 Return Value :-
4271         Sucess :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
4272         Failure :-Return negative error code
4273
4274
4275 **/
4276 INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
4277 {
4278
4279         INT Status = STATUS_SUCCESS ;
4280         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Section Value :%x \n", eFlash2xSectionVal);
4281
4282         if((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2))
4283         {
4284                 Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
4285         }
4286         else if(eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2)
4287         {
4288                 Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
4289         }
4290         else
4291         {
4292                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given Section <%d>does not have Header",eFlash2xSectionVal);
4293                 return STATUS_SUCCESS;
4294         }
4295         return Status;
4296 }
4297 /**
4298 BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
4299                                           header and  Write Permission.
4300 @Adapater :- Bcm Driver Private Data Structure
4301 @eFlashSectionVal :- Flash section val which has header
4302
4303 Return Value :-
4304         Sucess :- If Section is present and writable write the sig and return STATUS_SUCCESS
4305         Failure :-Return negative error code
4306
4307 **/
4308 INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
4309 {
4310
4311         UINT uiSignature = 0 ;
4312         UINT uiOffset = 0;
4313         //DSD_HEADER dsdHeader = {0};
4314
4315         if(Adapter->bSigCorrupted == FALSE)
4316         {
4317                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Signature is not corrupted by driver, hence not restoring\n");
4318                 return STATUS_SUCCESS;
4319         }
4320         if(Adapter->bAllDSDWriteAllow == FALSE)
4321         {
4322                 if(IsSectionWritable(Adapter,eFlashSectionVal) == FALSE)
4323                 {
4324                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Write signature");
4325                         return SECTOR_IS_NOT_WRITABLE;
4326                 }
4327         }
4328         if((eFlashSectionVal == DSD0) ||(eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2))
4329         {
4330                 uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER) ;
4331                 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader ;
4332
4333                 uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber);
4334
4335                 if((ReadDSDSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
4336                 {
4337                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corrupted Pattern is not there. Hence won't write sig");
4338                         return STATUS_FAILURE;
4339                 }
4340
4341         }
4342         else if((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2))
4343         {
4344                 uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
4345                 //uiOffset = 0;
4346                 uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber);
4347                 if((ReadISOSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
4348                 {
4349                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Currupted Pattern is not there. Hence won't write sig");
4350                         return STATUS_FAILURE;
4351                 }
4352         }
4353         else
4354         {
4355                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
4356                 return STATUS_FAILURE;
4357         }
4358
4359         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature");
4360
4361
4362         Adapter->bHeaderChangeAllowed = TRUE;
4363         Adapter->bSigCorrupted = FALSE;
4364         BcmFlash2xBulkWrite(Adapter, &uiSignature,eFlashSectionVal,uiOffset,SIGNATURE_SIZE,TRUE);
4365         Adapter->bHeaderChangeAllowed = FALSE;
4366
4367
4368
4369         return STATUS_SUCCESS;
4370 }
4371 /**
4372 validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
4373                                                       if requested Bytes goes beyond the Requested section, it reports error.
4374 @Adapater :- Bcm Driver Private Data Structure
4375 @psFlash2xReadWrite :-Flash2x Read/write structure pointer
4376
4377 Return values:-Return TRUE is request is valid else FALSE.
4378
4379
4380 **/
4381 INT     validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite)
4382 {
4383         UINT uiNumOfBytes = 0 ;
4384         UINT uiSectStartOffset = 0 ;
4385         UINT uiSectEndOffset = 0;
4386         uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
4387
4388         if(IsSectionExistInFlash(Adapter,psFlash2xReadWrite->Section) != TRUE)
4389         {
4390                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%x> does not exixt in Flash",psFlash2xReadWrite->Section);
4391                 return FALSE;
4392         }
4393         uiSectStartOffset = BcmGetSectionValStartOffset(Adapter,psFlash2xReadWrite->Section);
4394         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n",uiSectStartOffset,psFlash2xReadWrite->Section);
4395         if((psFlash2xReadWrite->Section == ISO_IMAGE1) ||(psFlash2xReadWrite->Section == ISO_IMAGE2))
4396         {
4397                 if(psFlash2xReadWrite->Section == ISO_IMAGE1)
4398                 {
4399                         uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1) -
4400                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1)+
4401                                                           BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART2) -
4402                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART2)+
4403                                                           BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART3) -
4404                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART3);
4405                 }
4406                 else if(psFlash2xReadWrite->Section == ISO_IMAGE2)
4407                 {
4408                         uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2) -
4409                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)+
4410                                                           BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART2) -
4411                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART2)+
4412                                                           BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART3) -
4413                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART3);
4414
4415                 }
4416
4417                 //since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset
4418                 //it should be added in startoffset. so that check done in last of this function can be valued.
4419                 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset ;
4420
4421                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Total size of the ISO Image :%x",uiSectEndOffset);
4422         }
4423         else
4424                 uiSectEndOffset   = BcmGetSectionValEndOffset(Adapter,psFlash2xReadWrite->Section);
4425         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x \n",uiSectEndOffset);
4426
4427         //Checking the boundary condition
4428         if((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
4429                 return TRUE;
4430         else
4431         {
4432                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid Request....");
4433                 return FALSE;
4434         }
4435
4436 }
4437
4438 /**
4439 IsFlash2x :- check for Flash 2.x
4440 @Adapater :- Bcm Driver Private Data Structure
4441
4442 Return value:-
4443         return TRUE if flah2.x of hgher version else return false.
4444 **/
4445
4446 INT IsFlash2x(PMINI_ADAPTER Adapter)
4447 {
4448         if(Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
4449                 return TRUE ;
4450         else
4451                 return FALSE;
4452 }
4453 /**
4454 GetFlashBaseAddr :- Calculate the Flash Base address
4455 @Adapater :- Bcm Driver Private Data Structure
4456
4457 Return Value:-
4458         Success :- Base Address of the Flash
4459 **/
4460
4461 static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter)
4462 {
4463
4464         UINT uiBaseAddr = 0;
4465
4466         if(Adapter->bDDRInitDone)
4467         {
4468                 /*
4469                 For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
4470                 In case of Raw Read... use the default value
4471                 */
4472                 if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
4473                         !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
4474                         )
4475                         uiBaseAddr = Adapter->uiFlashBaseAdd ;
4476                 else
4477                         uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
4478         }
4479         else
4480         {
4481                 /*
4482                 For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
4483                 In case of Raw Read... use the default value
4484                 */
4485                 if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
4486                         !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
4487                         )
4488                         uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4489                 else
4490                         uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4491         }
4492
4493         return uiBaseAddr ;
4494 }
4495 /**
4496 BcmCopySection :- This API is used to copy the One section in another. Both section should
4497                                     be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
4498
4499 @Adapater :- Bcm Driver Private Data Structure
4500 @SrcSection :- Source section From where data has to be copied
4501 @DstSection :- Destination section to which data has to be copied
4502 @offset :- Offset from/to  where data has to be copied from one section to another.
4503 @numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
4504                              in case of numofBytes  equal zero complete section will be copied.
4505
4506 Return Values-
4507         Sucess : Return STATUS_SUCCESS
4508         Faillure :- return negative error code
4509
4510 **/
4511
4512 INT     BcmCopySection(PMINI_ADAPTER Adapter,
4513                                                 FLASH2X_SECTION_VAL SrcSection,
4514                                                 FLASH2X_SECTION_VAL DstSection,
4515                                                 UINT offset,
4516                                                 UINT numOfBytes)
4517 {
4518         UINT BuffSize = 0 ;
4519         UINT BytesToBeCopied = 0;
4520         PUCHAR pBuff = NULL ;
4521         INT Status = STATUS_SUCCESS ;
4522         if(SrcSection == DstSection)
4523         {
4524                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source and Destination should be different ...try again");
4525                 return -EINVAL;
4526         }
4527         if((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2))
4528         {
4529                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source should be DSD subsection");
4530                 return  -EINVAL;
4531         }
4532         if((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2))
4533         {
4534                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destination should be DSD subsection");
4535                 return  -EINVAL;
4536         }
4537
4538         //if offset zero means have to copy complete secton
4539
4540         if(numOfBytes == 0)
4541         {
4542                 numOfBytes = BcmGetSectionValEndOffset(Adapter,SrcSection)
4543                                   - BcmGetSectionValStartOffset(Adapter,SrcSection);
4544
4545                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Section Size :0x%x",numOfBytes);
4546         }
4547
4548         if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,SrcSection)
4549                                   - BcmGetSectionValStartOffset(Adapter,SrcSection))
4550         {
4551                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
4552                                                 offset, numOfBytes);
4553                 return -EINVAL;
4554         }
4555
4556         if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,DstSection)
4557                                   - BcmGetSectionValStartOffset(Adapter,DstSection))
4558         {
4559                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
4560                                                 offset, numOfBytes);
4561                 return -EINVAL;
4562         }
4563
4564
4565         if(numOfBytes > Adapter->uiSectorSize )
4566                 BuffSize = Adapter->uiSectorSize;
4567         else
4568                 BuffSize = numOfBytes ;
4569
4570         pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL);
4571         if(pBuff == NULL)
4572         {
4573                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed.. ");
4574                 return -ENOMEM;
4575         }
4576
4577
4578         BytesToBeCopied = Adapter->uiSectorSize ;
4579         if(offset % Adapter->uiSectorSize)
4580                 BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
4581         if(BytesToBeCopied > numOfBytes)
4582                 BytesToBeCopied = numOfBytes ;
4583
4584
4585
4586         Adapter->bHeaderChangeAllowed = TRUE;
4587
4588         do
4589         {
4590                 Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset,BytesToBeCopied);
4591                 if(Status)
4592                 {
4593                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection,BytesToBeCopied);
4594                         break;
4595                 }
4596                 Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pBuff,DstSection,offset,BytesToBeCopied,FALSE);
4597                 if(Status)
4598                 {
4599                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection,BytesToBeCopied);
4600                         break;
4601                 }
4602                 offset = offset + BytesToBeCopied;
4603                 numOfBytes = numOfBytes - BytesToBeCopied ;
4604                 if(numOfBytes)
4605                 {
4606                         if(numOfBytes > Adapter->uiSectorSize )
4607                                 BytesToBeCopied = Adapter->uiSectorSize;
4608                         else
4609                                 BytesToBeCopied = numOfBytes;
4610                 }
4611         }while(numOfBytes > 0) ;
4612         kfree(pBuff);
4613         Adapter->bHeaderChangeAllowed = FALSE ;
4614         return Status;
4615 }
4616
4617 /**
4618 SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
4619 @Adapater :- Bcm Driver Private Data Structure
4620 @pBuff :- Data buffer that has to be written in sector having the header map.
4621 @uiOffset :- Flash offset that has to be written.
4622
4623 Return value :-
4624         Sucess :- On sucess return STATUS_SUCCESS
4625         Faillure :- Return negative error code
4626
4627 **/
4628
4629 INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset)
4630 {
4631         UINT offsetToProtect = 0,HeaderSizeToProtect =0;
4632         BOOLEAN bHasHeader = FALSE ;
4633         PUCHAR pTempBuff =NULL;
4634         UINT uiSectAlignAddr = 0;
4635         UINT sig = 0;
4636
4637         //making the offset sector alligned
4638         uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4639
4640
4641         if((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD2)- Adapter->uiSectorSize)||
4642         (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD1)- Adapter->uiSectorSize)||
4643         (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD0)- Adapter->uiSectorSize))
4644         {
4645
4646                 //offset from the sector boundry having the header map
4647                 offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
4648                 HeaderSizeToProtect = sizeof(DSD_HEADER);
4649                 bHasHeader = TRUE ;
4650         }
4651
4652         if(uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1) ||
4653                 uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2))
4654         {
4655                 offsetToProtect = 0;
4656                 HeaderSizeToProtect = sizeof(ISO_HEADER);
4657                 bHasHeader = TRUE;
4658         }
4659         //If Header is present overwrite passed buffer with this
4660         if(bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE))
4661         {
4662                 pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL);
4663                 if(pTempBuff == NULL)
4664                 {
4665                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed ");
4666                         return -ENOMEM;
4667                 }
4668                 //Read header
4669                 BeceemFlashBulkRead(Adapter,(PUINT)pTempBuff,(uiSectAlignAddr + offsetToProtect),HeaderSizeToProtect);
4670                 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pTempBuff ,HeaderSizeToProtect);
4671                 //Replace Buffer content with Header
4672                 memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect);
4673
4674                 kfree(pTempBuff);
4675         }
4676         if(bHasHeader && Adapter->bSigCorrupted)
4677         {
4678                 sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)));
4679                 sig = ntohl(sig);
4680                 if((sig & 0xFF000000) != CORRUPTED_PATTERN)
4681                 {
4682                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Desired pattern is not at sig offset. Hence won't restore");
4683                         Adapter->bSigCorrupted = FALSE;
4684                         return STATUS_SUCCESS;
4685                 }
4686                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Corrupted sig is :%X", sig);
4687                 *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)))= htonl(DSD_IMAGE_MAGIC_NUMBER);
4688                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature in Header Write only");
4689                 Adapter->bSigCorrupted = FALSE;
4690         }
4691
4692         return STATUS_SUCCESS ;
4693 }
4694
4695 /**
4696 BcmDoChipSelect : This will selcet the appropriate chip for writing.
4697 @Adapater :- Bcm Driver Private Data Structure
4698
4699 OutPut:-
4700         Select the Appropriate chip and retrn status Sucess
4701 **/
4702 static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset)
4703 {
4704         UINT FlashConfig = 0;
4705         INT ChipNum = 0;
4706         UINT GPIOConfig = 0;
4707         UINT PartNum = 0;
4708
4709         ChipNum = offset / FLASH_PART_SIZE ;
4710
4711         //
4712         // Chip Select mapping to enable flash0.
4713         // To select flash 0, we have to OR with (0<<12).
4714         // ORing 0 will have no impact so not doing that part.
4715         // In future if Chip select value changes from 0 to non zero,
4716         // That needs be taken care with backward comaptibility. No worries for now.
4717         //
4718
4719         /*
4720         SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
4721         if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
4722         Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
4723         power down modes (Idle mode/shutdown mode), the values in the register will be different.
4724         */
4725
4726         if(Adapter->SelectedChip == ChipNum)
4727                 return STATUS_SUCCESS;
4728
4729         //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum);
4730         Adapter->SelectedChip = ChipNum ;
4731
4732         //bit[13..12]  will select the appropriate chip
4733         rdmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
4734         rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4735
4736         {
4737                 switch(ChipNum)
4738                 {
4739                 case 0:
4740                         PartNum = 0;
4741                         break;
4742                 case 1:
4743                         PartNum = 3;
4744                         GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
4745                         break;
4746                 case 2:
4747                         PartNum = 1;
4748                         GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
4749                         break;
4750                 case 3:
4751                         PartNum = 2;
4752                         GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
4753                         break;
4754                 }
4755         }
4756         /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
4757             nothing to do... can return immediately.
4758             ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
4759             Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
4760             These values are not written by host other than during CHIP_SELECT.
4761         */
4762         if(PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
4763                 return STATUS_SUCCESS;
4764
4765         //clearing the bit[13..12]
4766         FlashConfig &= 0xFFFFCFFF;
4767         FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); //00
4768
4769         wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4770         udelay(100);
4771
4772         wrmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
4773         udelay(100);
4774
4775         return STATUS_SUCCESS;
4776
4777 }
4778 INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
4779 {
4780                 UINT uiDSDsig = 0;
4781                 //UINT sigoffsetInMap = 0;
4782                 //DSD_HEADER dsdHeader = {0};
4783
4784
4785                 //sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader;
4786
4787                 if(dsd != DSD0 && dsd != DSD1 && dsd != DSD2)
4788                 {
4789                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for DSDs");
4790                         return STATUS_FAILURE;
4791                 }
4792                 BcmFlash2xBulkRead(Adapter,
4793                                                    &uiDSDsig,
4794                                                    dsd,
4795                                                    Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber),
4796                                                    SIGNATURE_SIZE);
4797
4798                 uiDSDsig = ntohl(uiDSDsig);
4799                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD SIG :%x", uiDSDsig);
4800
4801                 return uiDSDsig ;
4802 }
4803 INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
4804 {
4805         //UINT priOffsetInMap = 0 ;
4806         unsigned int uiDSDPri = STATUS_FAILURE;
4807         //DSD_HEADER dsdHeader = {0};
4808         //priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
4809         if(IsSectionWritable(Adapter,dsd))
4810         {
4811                 if(ReadDSDSignature(Adapter,dsd)== DSD_IMAGE_MAGIC_NUMBER)
4812                 {
4813                         BcmFlash2xBulkRead(Adapter,
4814                                                            &uiDSDPri,
4815                                                            dsd,
4816                                                            Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader +FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
4817                                                            4);
4818
4819                         uiDSDPri = ntohl(uiDSDPri);
4820                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD<%x> Priority :%x", dsd, uiDSDPri);
4821
4822                 }
4823         }
4824         return uiDSDPri;
4825 }
4826 FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter)
4827 {
4828         INT DSDHighestPri = STATUS_FAILURE;
4829         INT  DsdPri= 0 ;
4830         FLASH2X_SECTION_VAL HighestPriDSD = 0 ;
4831
4832         if(IsSectionWritable(Adapter,DSD2))
4833         {
4834                 DSDHighestPri = ReadDSDPriority(Adapter,DSD2);
4835                 HighestPriDSD = DSD2 ;
4836         }
4837         if(IsSectionWritable(Adapter,DSD1))
4838         {
4839                  DsdPri = ReadDSDPriority(Adapter,DSD1);
4840                  if(DSDHighestPri  < DsdPri)
4841                  {
4842                         DSDHighestPri = DsdPri ;
4843                         HighestPriDSD = DSD1;
4844                  }
4845         }
4846         if(IsSectionWritable(Adapter,DSD0))
4847         {
4848                  DsdPri = ReadDSDPriority(Adapter,DSD0);
4849                  if(DSDHighestPri  < DsdPri)
4850                  {
4851                         DSDHighestPri = DsdPri ;
4852                         HighestPriDSD = DSD0;
4853                  }
4854         }
4855         if(HighestPriDSD)
4856                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest DSD :%x , and its  Pri :%x", HighestPriDSD, DSDHighestPri);
4857         return  HighestPriDSD ;
4858 }
4859
4860 INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
4861 {
4862                 UINT uiISOsig = 0;
4863                 //UINT sigoffsetInMap = 0;
4864                 //ISO_HEADER ISOHeader = {0};
4865
4866
4867                 //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
4868
4869                 if(iso != ISO_IMAGE1 && iso != ISO_IMAGE2)
4870                 {
4871                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for ISOs");
4872                         return STATUS_FAILURE;
4873                 }
4874                 BcmFlash2xBulkRead(Adapter,
4875                                                    &uiISOsig,
4876                                                    iso,
4877                                                    0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber),
4878                                                    SIGNATURE_SIZE);
4879
4880                 uiISOsig = ntohl(uiISOsig);
4881                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO SIG :%x", uiISOsig);
4882
4883                 return uiISOsig ;
4884 }
4885 INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
4886 {
4887
4888         unsigned int ISOPri = STATUS_FAILURE;
4889         if(IsSectionWritable(Adapter,iso))
4890         {
4891                 if(ReadISOSignature(Adapter,iso)== ISO_IMAGE_MAGIC_NUMBER)
4892                 {
4893                         BcmFlash2xBulkRead(Adapter,
4894                                                            &ISOPri,
4895                                                            iso,
4896                                                            0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
4897                                                            4);
4898
4899                         ISOPri = ntohl(ISOPri);
4900                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO<%x> Priority :%x", iso, ISOPri);
4901
4902                 }
4903         }
4904         return ISOPri;
4905 }
4906 FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter)
4907 {
4908         INT ISOHighestPri = STATUS_FAILURE;
4909         INT  ISOPri= 0 ;
4910         FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL ;
4911
4912         if(IsSectionWritable(Adapter,ISO_IMAGE2))
4913         {
4914                 ISOHighestPri = ReadISOPriority(Adapter,ISO_IMAGE2);
4915                 HighestPriISO = ISO_IMAGE2 ;
4916         }
4917         if(IsSectionWritable(Adapter,ISO_IMAGE1))
4918         {
4919                  ISOPri = ReadISOPriority(Adapter,ISO_IMAGE1);
4920                  if(ISOHighestPri  < ISOPri)
4921                  {
4922                         ISOHighestPri = ISOPri ;
4923                         HighestPriISO = ISO_IMAGE1;
4924                  }
4925         }
4926         if(HighestPriISO)
4927                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest ISO :%x and its Pri :%x",HighestPriISO,ISOHighestPri);
4928         return  HighestPriISO ;
4929 }
4930 INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
4931                                                                                 PUINT pBuff,
4932                                                                                 FLASH2X_SECTION_VAL eFlash2xSectionVal,
4933                                                                                 UINT uiOffset,
4934                                                                                 UINT uiNumBytes
4935                                                                                 )
4936 {
4937 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
4938         UINT uiTemp = 0, value = 0 ;
4939         UINT i = 0;
4940         UINT uiPartOffset = 0;
4941 #endif
4942         UINT uiStartOffset = 0;
4943         //Adding section start address
4944         INT Status = STATUS_SUCCESS;
4945         PUCHAR pcBuff = (PUCHAR)pBuff;
4946
4947         if(uiNumBytes % Adapter->ulFlashWriteSize)
4948         {
4949                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
4950                 return STATUS_FAILURE;
4951         }
4952
4953         uiStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
4954
4955         if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
4956         {
4957                 return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
4958         }
4959
4960         uiOffset = uiOffset + uiStartOffset;
4961
4962 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
4963   Status = bcmflash_raw_writenoerase((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE), pcBuff,uiNumBytes);
4964 #else
4965         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4966         value = 0;
4967         wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
4968
4969         Adapter->SelectedChip = RESET_CHIP_SELECT;
4970         BcmDoChipSelect(Adapter,uiOffset);
4971         uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
4972
4973         for(i = 0 ; i< uiNumBytes; i += Adapter->ulFlashWriteSize)
4974         {
4975                 if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
4976                         Status = flashByteWrite(Adapter,uiPartOffset, pcBuff);
4977                 else
4978                         Status = flashWrite(Adapter,uiPartOffset, pcBuff);
4979
4980                 if(Status != STATUS_SUCCESS)
4981                         break;
4982
4983                 pcBuff = pcBuff + Adapter->ulFlashWriteSize;
4984                 uiPartOffset = uiPartOffset +  Adapter->ulFlashWriteSize;
4985         }
4986         wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4987         Adapter->SelectedChip = RESET_CHIP_SELECT;
4988 #endif
4989
4990         return Status;
4991 }
4992
4993 BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
4994 {
4995
4996         BOOLEAN SectionPresent = FALSE ;
4997
4998         switch(section)
4999         {
5000
5001                 case ISO_IMAGE1 :
5002                           if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
5003                                         (IsNonCDLessDevice(Adapter) == FALSE))
5004                                   SectionPresent = TRUE ;
5005                            break;
5006                 case ISO_IMAGE2 :
5007                                 if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
5008                                         (IsNonCDLessDevice(Adapter) == FALSE))
5009                                          SectionPresent = TRUE ;
5010                           break;
5011                 case DSD0 :
5012                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
5013                                          SectionPresent = TRUE ;
5014                                 break;
5015                 case DSD1 :
5016                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
5017                                          SectionPresent = TRUE ;
5018                                 break;
5019                 case DSD2 :
5020                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
5021                                          SectionPresent = TRUE ;
5022                                 break;
5023                 case VSA0 :
5024                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
5025                                          SectionPresent = TRUE ;
5026                                 break;
5027                 case VSA1 :
5028                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
5029                                          SectionPresent = TRUE ;
5030                                 break;
5031                 case VSA2 :
5032                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
5033                                          SectionPresent = TRUE ;
5034                                 break;
5035                 case SCSI :
5036                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
5037                                          SectionPresent = TRUE ;
5038                                 break;
5039                 case CONTROL_SECTION :
5040                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
5041                                          SectionPresent = TRUE ;
5042                                 break;
5043                 default :
5044                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
5045                         SectionPresent =  FALSE;
5046         }
5047         return SectionPresent ;
5048 }
5049 INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section)
5050 {
5051                 INT offset = STATUS_FAILURE;
5052                 INT Status = FALSE;
5053                 if(IsSectionExistInFlash(Adapter,Section) == FALSE)
5054                 {
5055                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section <%d> does not exixt", Section);
5056                         return FALSE;
5057                 }
5058                 offset = BcmGetSectionValStartOffset(Adapter,Section);
5059                 if(offset == INVALID_OFFSET)
5060                 {
5061                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%d> does not exixt", Section);
5062                         return FALSE;
5063                 }
5064
5065                 if(IsSectionExistInVendorInfo(Adapter,Section))
5066                 {
5067                         return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
5068                 }
5069
5070                 Status = IsOffsetWritable(Adapter,offset);
5071                 return Status ;
5072 }
5073
5074 static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
5075 {
5076
5077         PUCHAR pBuff = NULL;
5078         UINT sig = 0;
5079         UINT uiOffset = 0;
5080         UINT BlockStatus = 0;
5081         UINT uiSectAlignAddr = 0;
5082
5083         Adapter->bSigCorrupted = FALSE;
5084
5085         if(Adapter->bAllDSDWriteAllow == FALSE)
5086         {
5087                 if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
5088                 {
5089                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
5090                         return SECTOR_IS_NOT_WRITABLE;
5091                 }
5092         }
5093
5094         pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
5095         if(pBuff == NULL)
5096         {
5097                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
5098                 return -ENOMEM ;
5099         }
5100
5101         uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER);
5102         uiOffset -= MAX_RW_SIZE ;
5103
5104         BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset,MAX_RW_SIZE);
5105
5106
5107         sig = *((PUINT)(pBuff +12));
5108         sig =ntohl(sig);
5109         BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
5110         //Now corrupting the sig by corrupting 4th last Byte.
5111         *(pBuff + 12) = 0;
5112
5113         if(sig == DSD_IMAGE_MAGIC_NUMBER)
5114         {
5115                 Adapter->bSigCorrupted = TRUE;
5116                 if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
5117                 {
5118                         uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize -1);
5119                         BlockStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);
5120
5121                         WriteToFlashWithoutSectorErase(Adapter,(PUINT)(pBuff + 12),eFlash2xSectionVal,
5122                                                                                                 (uiOffset + 12),BYTE_WRITE_SUPPORT);
5123                         if(BlockStatus)
5124                         {
5125                                 BcmRestoreBlockProtectStatus(Adapter,BlockStatus);
5126                                 BlockStatus = 0;
5127                         }
5128                 }
5129                 else
5130                 {
5131                         WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
5132                                                                                                 uiOffset ,MAX_RW_SIZE);
5133                 }
5134         }
5135         else
5136         {
5137                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
5138                 kfree(pBuff);
5139                 return STATUS_FAILURE;
5140         }
5141
5142         kfree(pBuff);
5143         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
5144         return STATUS_SUCCESS ;
5145 }
5146
5147 static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
5148 {
5149
5150         PUCHAR pBuff = NULL;
5151         UINT sig = 0;
5152         UINT uiOffset = 0;
5153
5154         Adapter->bSigCorrupted = FALSE;
5155
5156         if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
5157         {
5158                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
5159                 return SECTOR_IS_NOT_WRITABLE;
5160         }
5161
5162         pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
5163         if(pBuff == NULL)
5164         {
5165                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allocate memorey");
5166                 return -ENOMEM ;
5167         }
5168
5169         uiOffset = 0;
5170
5171         BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset, MAX_RW_SIZE);
5172
5173         sig = *((PUINT)pBuff);
5174         sig =ntohl(sig);
5175
5176         //corrupt signature
5177         *pBuff = 0;
5178
5179         if(sig == ISO_IMAGE_MAGIC_NUMBER)
5180         {
5181                 Adapter->bSigCorrupted = TRUE;
5182                 WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
5183                                                                                         uiOffset ,Adapter->ulFlashWriteSize);
5184         }
5185         else
5186         {
5187                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
5188                 kfree(pBuff);
5189                 return STATUS_FAILURE;
5190         }
5191
5192         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
5193         BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
5194
5195         kfree(pBuff);
5196         return STATUS_SUCCESS ;
5197 }
5198
5199 BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter)
5200 {
5201         if(Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
5202                 return TRUE;
5203         else
5204                 return FALSE ;
5205 }
5206