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