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