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