packaging: release out (3.8.3)
[profile/ivi/kernel-adaptation-intel-automotive.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 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(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         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 = (PFLASH_CS_INFO)kzalloc(sizeof(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 = (PFLASH2X_CS_INFO)kzalloc(sizeof(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 = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_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(PFLASH2X_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(PFLASH2X_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(PFLASH_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(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(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(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         /* 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(FLASH_CS_INFO));
2526         memset(Adapter->psFlash2xCSInfo, 0 , sizeof(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(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(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 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         case ISO_IMAGE1_PART2:
2814                 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS)
2815                         SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
2816                 break;
2817         case ISO_IMAGE1_PART3:
2818                 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS)
2819                         SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
2820                 break;
2821         case ISO_IMAGE2_PART2:
2822                 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
2823                         SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
2824                 break;
2825         case ISO_IMAGE2_PART3:
2826                 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS)
2827                         SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
2828                 break;
2829         default:
2830                 SectEndOffset = INVALID_OFFSET;
2831         }
2832
2833         return SectEndOffset ;
2834 }
2835
2836 /*
2837  * BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
2838  * @Adapter :Driver Private Data Structure
2839  * @pBuffer : Buffer where data has to be put after reading
2840  * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
2841  * @uiOffsetWithinSectionVal :- Offset with in provided section
2842  * @uiNumBytes : Number of Bytes for Read
2843  *
2844  * Return value:-
2845  * return true on success and STATUS_FAILURE on fail.
2846  */
2847
2848 int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
2849                 PUINT pBuffer,
2850                 enum bcm_flash2x_section_val eFlash2xSectionVal,
2851                 unsigned int uiOffsetWithinSectionVal,
2852                 unsigned int uiNumBytes)
2853 {
2854         int Status = STATUS_SUCCESS;
2855         int SectionStartOffset = 0;
2856         unsigned int uiAbsoluteOffset = 0;
2857         unsigned int uiTemp = 0, value = 0;
2858
2859         if (!Adapter) {
2860                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
2861                 return -EINVAL;
2862         }
2863         if (Adapter->device_removed) {
2864                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
2865                 return -ENODEV;
2866         }
2867
2868         /* NO_SECTION_VAL means absolute offset is given. */
2869         if (eFlash2xSectionVal == NO_SECTION_VAL)
2870                 SectionStartOffset = 0;
2871         else
2872                 SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
2873
2874         if (SectionStartOffset == STATUS_FAILURE) {
2875                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash 2.x Map ", eFlash2xSectionVal);
2876                 return -EINVAL;
2877         }
2878
2879         if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
2880                 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
2881
2882         /* calculating  the absolute offset from FLASH; */
2883         uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
2884         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2885         value = 0;
2886         wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2887         Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes);
2888         wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2889         if (Status) {
2890                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
2891                 return Status;
2892         }
2893
2894         return Status;
2895 }
2896
2897 /*
2898  * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
2899  * @Adapter :Driver Private Data Structure
2900  * @pBuffer : Buffer From where data has to taken for writing
2901  * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
2902  * @uiOffsetWithinSectionVal :- Offset with in provided section
2903  * @uiNumBytes : Number of Bytes for Write
2904  *
2905  * Return value:-
2906  * return true on success and STATUS_FAILURE on fail.
2907  *
2908  */
2909
2910 int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
2911                         PUINT pBuffer,
2912                         enum bcm_flash2x_section_val eFlash2xSectVal,
2913                         unsigned int uiOffset,
2914                         unsigned int uiNumBytes,
2915                         unsigned int bVerify)
2916 {
2917         int Status = STATUS_SUCCESS;
2918         unsigned int FlashSectValStartOffset = 0;
2919         unsigned int uiTemp = 0, value = 0;
2920
2921         if (!Adapter) {
2922                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
2923                 return -EINVAL;
2924         }
2925
2926         if (Adapter->device_removed) {
2927                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
2928                 return -ENODEV;
2929         }
2930
2931         /* NO_SECTION_VAL means absolute offset is given. */
2932         if (eFlash2xSectVal == NO_SECTION_VAL)
2933                 FlashSectValStartOffset = 0;
2934         else
2935                 FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal);
2936
2937         if (FlashSectValStartOffset == STATUS_FAILURE) {
2938                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash Map 2.x", eFlash2xSectVal);
2939                 return -EINVAL;
2940         }
2941
2942         if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal))
2943                 return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
2944
2945         /* calculating  the absolute offset from FLASH; */
2946         uiOffset = uiOffset + FlashSectValStartOffset;
2947
2948         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2949         value = 0;
2950         wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2951
2952         Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify);
2953
2954         wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2955         if (Status) {
2956                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
2957                 return Status;
2958         }
2959
2960         return Status;
2961 }
2962
2963 /*
2964  * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
2965  * @Adapter :-Drivers private Data Structure
2966  *
2967  * Return Value:-
2968  * Return STATUS_SUCESS if get success in setting the right DSD else negaive error code
2969  *
2970  */
2971
2972 static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter)
2973 {
2974         enum bcm_flash2x_section_val uiHighestPriDSD = 0;
2975
2976         uiHighestPriDSD = getHighestPriDSD(Adapter);
2977         Adapter->eActiveDSD = uiHighestPriDSD;
2978
2979         if (DSD0  == uiHighestPriDSD)
2980                 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
2981         if (DSD1 == uiHighestPriDSD)
2982                 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
2983         if (DSD2 == uiHighestPriDSD)
2984                 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
2985         if (Adapter->eActiveDSD)
2986                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
2987         if (Adapter->eActiveDSD == 0) {
2988                 /* if No DSD gets Active, Make Active the DSD with WR  permission */
2989                 if (IsSectionWritable(Adapter, DSD2)) {
2990                         Adapter->eActiveDSD = DSD2;
2991                         Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
2992                 } else if (IsSectionWritable(Adapter, DSD1)) {
2993                         Adapter->eActiveDSD = DSD1;
2994                         Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
2995                 } else if (IsSectionWritable(Adapter, DSD0)) {
2996                         Adapter->eActiveDSD = DSD0;
2997                         Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
2998                 }
2999         }
3000
3001         return STATUS_SUCCESS;
3002 }
3003
3004 /*
3005  * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
3006  * @Adapter : Driver private Data Structure
3007  *
3008  * Return Value:-
3009  * Sucsess:- STATUS_SUCESS
3010  * Failure- : negative erro code
3011  *
3012  */
3013
3014 static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter)
3015 {
3016         int HighestPriISO = 0;
3017
3018         HighestPriISO = getHighestPriISO(Adapter);
3019
3020         Adapter->eActiveISO = HighestPriISO;
3021         if (Adapter->eActiveISO == ISO_IMAGE2)
3022                 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
3023         else if (Adapter->eActiveISO == ISO_IMAGE1)
3024                 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3025
3026         if (Adapter->eActiveISO)
3027                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO);
3028
3029         return STATUS_SUCCESS;
3030 }
3031
3032 /*
3033  * IsOffsetWritable :- it will tell the access permission of the sector having passed offset
3034  * @Adapter : Drivers Private Data Structure
3035  * @uiOffset : Offset provided in the Flash
3036  *
3037  * Return Value:-
3038  * Success:-TRUE ,  offset is writable
3039  * Failure:-FALSE, offset is RO
3040  *
3041  */
3042
3043 B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset)
3044 {
3045         unsigned int uiSectorNum = 0;
3046         unsigned int uiWordOfSectorPermission = 0;
3047         unsigned int uiBitofSectorePermission = 0;
3048         B_UINT32 permissionBits = 0;
3049
3050         uiSectorNum = uiOffset/Adapter->uiSectorSize;
3051
3052         /* calculating the word having this Sector Access permission from SectorAccessBitMap Array */
3053         uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16];
3054
3055         /* calculating the bit index inside the word for  this sector */
3056         uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16);
3057
3058         /* Setting Access permission */
3059         permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission);
3060         permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
3061         if (permissionBits == SECTOR_READWRITE_PERMISSION)
3062                 return TRUE;
3063         else
3064                 return FALSE;
3065 }
3066
3067 static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap)
3068 {
3069         struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
3070
3071         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
3072         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE1  :0X%x", psFlash2xBitMap->ISO_IMAGE1);
3073         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE2  :0X%x", psFlash2xBitMap->ISO_IMAGE2);
3074         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD0  :0X%x", psFlash2xBitMap->DSD0);
3075         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD1  :0X%x", psFlash2xBitMap->DSD1);
3076         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD2  :0X%x", psFlash2xBitMap->DSD2);
3077         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA0  :0X%x", psFlash2xBitMap->VSA0);
3078         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA1  :0X%x", psFlash2xBitMap->VSA1);
3079         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA2  :0X%x", psFlash2xBitMap->VSA2);
3080         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSI  :0X%x", psFlash2xBitMap->SCSI);
3081         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CONTROL_SECTION  :0X%x", psFlash2xBitMap->CONTROL_SECTION);
3082
3083         return STATUS_SUCCESS;
3084 }
3085
3086 /*
3087  * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
3088  * 8bit has been assigned to every section.
3089  * bit[0] :Section present or not
3090  * bit[1] :section is valid or not
3091  * bit[2] : Secton is read only or has write permission too.
3092  * bit[3] : Active Section -
3093  * bit[7...4] = Reserved .
3094  *
3095  * @Adapter:-Driver private Data Structure
3096  *
3097  * Return value:-
3098  * Success:- STATUS_SUCESS
3099  * Failure:- negative error code
3100  */
3101
3102 int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap)
3103 {
3104         PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
3105         enum bcm_flash2x_section_val uiHighestPriDSD = 0;
3106         enum bcm_flash2x_section_val uiHighestPriISO = 0;
3107         BOOLEAN SetActiveDSDDone = FALSE;
3108         BOOLEAN SetActiveISODone = FALSE;
3109
3110         /* For 1.x map all the section except DSD0 will be shown as not present
3111          * This part will be used by calibration tool to detect the number of DSD present in Flash.
3112          */
3113         if (IsFlash2x(Adapter) == FALSE) {
3114                 psFlash2xBitMap->ISO_IMAGE2 = 0;
3115                 psFlash2xBitMap->ISO_IMAGE1 = 0;
3116                 psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */
3117                 psFlash2xBitMap->DSD1  = 0;
3118                 psFlash2xBitMap->DSD2 = 0;
3119                 psFlash2xBitMap->VSA0 = 0;
3120                 psFlash2xBitMap->VSA1 = 0;
3121                 psFlash2xBitMap->VSA2 = 0;
3122                 psFlash2xBitMap->CONTROL_SECTION = 0;
3123                 psFlash2xBitMap->SCSI = 0;
3124                 psFlash2xBitMap->Reserved0 = 0;
3125                 psFlash2xBitMap->Reserved1 = 0;
3126                 psFlash2xBitMap->Reserved2 = 0;
3127
3128                 return STATUS_SUCCESS;
3129         }
3130
3131         uiHighestPriDSD = getHighestPriDSD(Adapter);
3132         uiHighestPriISO = getHighestPriISO(Adapter);
3133
3134         /*
3135          * IS0 IMAGE 2
3136          */
3137         if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) {
3138                 /* Setting the 0th Bit representing the Section is present or not. */
3139                 psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
3140
3141                 if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER)
3142                         psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
3143
3144                 /* Calculation for extrating the Access permission */
3145                 if (IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
3146                         psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
3147
3148                 if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) {
3149                         psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT;
3150                         SetActiveISODone = TRUE;
3151                 }
3152         }
3153
3154         /*
3155          * IS0 IMAGE 1
3156          */
3157         if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) {
3158                 /* Setting the 0th Bit representing the Section is present or not. */
3159                 psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
3160
3161                 if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
3162                         psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
3163
3164                 /* Calculation for extrating the Access permission */
3165                 if (IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
3166                         psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
3167
3168                 if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) {
3169                         psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT;
3170                         SetActiveISODone = TRUE;
3171                 }
3172         }
3173
3174         /*
3175          * DSD2
3176          */
3177         if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) {
3178                 /* Setting the 0th Bit representing the Section is present or not. */
3179                 psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
3180
3181                 if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER)
3182                         psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
3183
3184                 /* Calculation for extrating the Access permission */
3185                 if (IsSectionWritable(Adapter, DSD2) == FALSE) {
3186                         psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
3187                 } else {
3188                         /* Means section is writable */
3189                         if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) {
3190                                 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT;
3191                                 SetActiveDSDDone = TRUE;
3192                         }
3193                 }
3194         }
3195
3196         /*
3197          * DSD 1
3198          */
3199         if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) {
3200                 /* Setting the 0th Bit representing the Section is present or not. */
3201                 psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
3202
3203                 if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER)
3204                         psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
3205
3206                 /* Calculation for extrating the Access permission */
3207                 if (IsSectionWritable(Adapter, DSD1) == FALSE) {
3208                         psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
3209                 } else {
3210                         /* Means section is writable */
3211                         if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) {
3212                                 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT;
3213                                 SetActiveDSDDone = TRUE;
3214                         }
3215                 }
3216         }
3217
3218         /*
3219          * For DSD 0
3220          */
3221         if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) {
3222                 /* Setting the 0th Bit representing the Section is present or not. */
3223                 psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
3224
3225                 if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER)
3226                         psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
3227
3228                 /* Setting Access permission */
3229                 if (IsSectionWritable(Adapter, DSD0) == FALSE) {
3230                         psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
3231                 } else {
3232                         /* Means section is writable */
3233                         if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD0)) {
3234                                 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT;
3235                                 SetActiveDSDDone = TRUE;
3236                         }
3237                 }
3238         }
3239
3240         /*
3241          * VSA 0
3242          */
3243         if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) {
3244                 /* Setting the 0th Bit representing the Section is present or not. */
3245                 psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
3246
3247                 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3248                 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
3249
3250                 /* Calculation for extrating the Access permission */
3251                 if (IsSectionWritable(Adapter, VSA0) == FALSE)
3252                         psFlash2xBitMap->VSA0 |=  FLASH2X_SECTION_RO;
3253
3254                 /* By Default section is Active */
3255                 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT;
3256         }
3257
3258         /*
3259          * VSA 1
3260          */
3261         if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) {
3262                 /* Setting the 0th Bit representing the Section is present or not. */
3263                 psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
3264
3265                 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3266                 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID;
3267
3268                 /* Checking For Access permission */
3269                 if (IsSectionWritable(Adapter, VSA1) == FALSE)
3270                         psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
3271
3272                 /* By Default section is Active */
3273                 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT;
3274         }
3275
3276         /*
3277          * VSA 2
3278          */
3279         if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) {
3280                 /* Setting the 0th Bit representing the Section is present or not. */
3281                 psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
3282
3283                 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3284                 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
3285
3286                 /* Checking For Access permission */
3287                 if (IsSectionWritable(Adapter, VSA2) == FALSE)
3288                         psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
3289
3290                 /* By Default section is Active */
3291                 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT;
3292         }
3293
3294         /*
3295          * SCSI Section
3296          */
3297         if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) {
3298                 /* Setting the 0th Bit representing the Section is present or not. */
3299                 psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
3300
3301                 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3302                 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID;
3303
3304                 /* Checking For Access permission */
3305                 if (IsSectionWritable(Adapter, SCSI) == FALSE)
3306                         psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
3307
3308                 /* By Default section is Active */
3309                 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT;
3310         }
3311
3312         /*
3313          * Control Section
3314          */
3315         if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) {
3316                 /* Setting the 0th Bit representing the Section is present or not. */
3317                 psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
3318
3319                 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3320                 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
3321
3322                 /* Checking For Access permission */
3323                 if (IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
3324                         psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
3325
3326                 /* By Default section is Active */
3327                 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT;
3328         }
3329
3330         /*
3331          * For Reserved Sections
3332          */
3333         psFlash2xBitMap->Reserved0 = 0;
3334         psFlash2xBitMap->Reserved0 = 0;
3335         psFlash2xBitMap->Reserved0 = 0;
3336         BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
3337
3338         return STATUS_SUCCESS;
3339 }
3340
3341 /*
3342  * BcmSetActiveSection :- Set Active section is used to make priority field highest over other
3343  * section of same type.
3344  *
3345  * @Adapater :- Bcm Driver Private Data Structure
3346  * @eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
3347  *
3348  * Return Value:- Make the priorit highest else return erorr code
3349  *
3350  */
3351
3352 int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal)
3353 {
3354         unsigned int SectImagePriority = 0;
3355         int Status = STATUS_SUCCESS;
3356
3357         /* DSD_HEADER sDSD = {0};
3358          * ISO_HEADER sISO = {0};
3359          */
3360         int HighestPriDSD = 0 ;
3361         int HighestPriISO = 0;
3362
3363         Status = IsSectionWritable(Adapter, eFlash2xSectVal);
3364         if (Status != TRUE) {
3365                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal);
3366                 return STATUS_FAILURE;
3367         }
3368
3369         Adapter->bHeaderChangeAllowed = TRUE;
3370         switch (eFlash2xSectVal) {
3371         case ISO_IMAGE1:
3372         case ISO_IMAGE2:
3373                 if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) {
3374                         HighestPriISO = getHighestPriISO(Adapter);
3375
3376                         if (HighestPriISO == eFlash2xSectVal) {
3377                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
3378                                 Status = STATUS_SUCCESS;
3379                                 break;
3380                         }
3381
3382                         SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
3383
3384                         if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) {
3385                                 /* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
3386                                  * We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
3387                                  * by user
3388                                  */
3389                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
3390                                 SectImagePriority = htonl(0x1);
3391                                 Status = BcmFlash2xBulkWrite(Adapter,
3392                                                         &SectImagePriority,
3393                                                         HighestPriISO,
3394                                                         0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
3395                                                         SIGNATURE_SIZE,
3396                                                         TRUE);
3397                                 if (Status) {
3398                                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3399                                         Status = STATUS_FAILURE;
3400                                         break;
3401                                 }
3402
3403                                 HighestPriISO = getHighestPriISO(Adapter);
3404
3405                                 if (HighestPriISO == eFlash2xSectVal) {
3406                                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
3407                                         Status = STATUS_SUCCESS;
3408                                         break;
3409                                 }
3410
3411                                 SectImagePriority = 2;
3412                         }
3413
3414                         SectImagePriority = htonl(SectImagePriority);
3415
3416                         Status = BcmFlash2xBulkWrite(Adapter,
3417                                                 &SectImagePriority,
3418                                                 eFlash2xSectVal,
3419                                                 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
3420                                                 SIGNATURE_SIZE,
3421                                                 TRUE);
3422                         if (Status) {
3423                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3424                                 break;
3425                         }
3426                 } else {
3427                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3428                         Status = STATUS_FAILURE;
3429                         break;
3430                 }
3431                 break;
3432         case DSD0:
3433         case DSD1:
3434         case DSD2:
3435                 if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) {
3436                         HighestPriDSD = getHighestPriDSD(Adapter);
3437                         if ((HighestPriDSD == eFlash2xSectVal)) {
3438                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal);
3439                                 Status = STATUS_SUCCESS;
3440                                 break;
3441                         }
3442
3443                         SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1;
3444                         if (SectImagePriority <= 0) {
3445                                 /* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
3446                                  * We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
3447                                  * by user
3448                                  */
3449                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
3450                                 SectImagePriority = htonl(0x1);
3451
3452                                 Status = BcmFlash2xBulkWrite(Adapter,
3453                                                         &SectImagePriority,
3454                                                         HighestPriDSD,
3455                                                         Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3456                                                         SIGNATURE_SIZE,
3457                                                         TRUE);
3458                                 if (Status) {
3459                                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3460                                         break;
3461                                 }
3462
3463                                 HighestPriDSD = getHighestPriDSD(Adapter);
3464
3465                                 if ((HighestPriDSD == eFlash2xSectVal)) {
3466                                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
3467                                         Status = STATUS_SUCCESS;
3468                                         break;
3469                                 }
3470
3471                                 SectImagePriority = htonl(0x2);
3472                                 Status = BcmFlash2xBulkWrite(Adapter,
3473                                                         &SectImagePriority,
3474                                                         HighestPriDSD,
3475                                                         Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3476                                                         SIGNATURE_SIZE,
3477                                                         TRUE);
3478                                 if (Status) {
3479                                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3480                                         break;
3481                                 }
3482
3483                                 HighestPriDSD = getHighestPriDSD(Adapter);
3484                                 if ((HighestPriDSD == eFlash2xSectVal)) {
3485                                         Status = STATUS_SUCCESS;
3486                                         break;
3487                                 }
3488
3489                                 SectImagePriority = 3;
3490                         }
3491                         SectImagePriority = htonl(SectImagePriority);
3492                         Status = BcmFlash2xBulkWrite(Adapter,
3493                                                 &SectImagePriority,
3494                                                 eFlash2xSectVal,
3495                                                 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3496                                                 SIGNATURE_SIZE,
3497                                                 TRUE);
3498                         if (Status) {
3499                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3500                                 Status = STATUS_FAILURE;
3501                                 break;
3502                         }
3503                 } else {
3504                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3505                         Status = STATUS_FAILURE;
3506                         break;
3507                 }
3508                 break;
3509         case VSA0:
3510         case VSA1:
3511         case VSA2:
3512                 /* Has to be decided */
3513                 break;
3514         default:
3515                 Status = STATUS_FAILURE;
3516                 break;
3517         }
3518
3519         Adapter->bHeaderChangeAllowed = FALSE;
3520         return Status;
3521 }
3522
3523 /*
3524  * BcmCopyISO - Used only for copying the ISO section
3525  * @Adapater :- Bcm Driver Private Data Structure
3526  * @sCopySectStrut :- Section copy structure
3527  *
3528  * Return value:- SUCCESS if copies successfully else negative error code
3529  *
3530  */
3531
3532 int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut)
3533 {
3534         PCHAR Buff = NULL;
3535         enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0;
3536         unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
3537         unsigned int uiTotalDataToCopy = 0;
3538         BOOLEAN IsThisHeaderSector = FALSE;
3539         unsigned int sigOffset = 0;
3540         unsigned int ISOLength = 0;
3541         unsigned int Status = STATUS_SUCCESS;
3542         unsigned int SigBuff[MAX_RW_SIZE];
3543         unsigned int i = 0;
3544
3545         if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) {
3546                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3547                 return STATUS_FAILURE;
3548         }
3549
3550         Status = BcmFlash2xBulkRead(Adapter,
3551                                 &ISOLength,
3552                                 sCopySectStrut.SrcSection,
3553                                 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageSize),
3554                                 4);
3555         if (Status) {
3556                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
3557                 return Status;
3558         }
3559
3560         ISOLength = htonl(ISOLength);
3561         if (ISOLength % Adapter->uiSectorSize)
3562                 ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize);
3563
3564         sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);
3565
3566         Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
3567
3568         if (!Buff) {
3569                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size");
3570                 return -ENOMEM;
3571         }
3572
3573         if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) {
3574                 eISOReadPart = ISO_IMAGE1;
3575                 eISOWritePart = ISO_IMAGE2;
3576                 uiReadOffsetWithinPart =  0;
3577                 uiWriteOffsetWithinPart = 0;
3578
3579                 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
3580                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
3581                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
3582                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
3583                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
3584                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3585
3586                 if (uiTotalDataToCopy < ISOLength) {
3587                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3588                         Status = STATUS_FAILURE;
3589                         goto out;
3590                 }
3591
3592                 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
3593                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
3594                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
3595                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
3596                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
3597                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3598
3599                 if (uiTotalDataToCopy < ISOLength) {
3600                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
3601                         Status = STATUS_FAILURE;
3602                         goto out;
3603                 }
3604
3605                 uiTotalDataToCopy = ISOLength;
3606
3607                 CorruptISOSig(Adapter, ISO_IMAGE2);
3608                 while (uiTotalDataToCopy) {
3609                         if (uiTotalDataToCopy == Adapter->uiSectorSize) {
3610                                 /* Setting for write of first sector. First sector is assumed to be written in last */
3611                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
3612                                 eISOReadPart = ISO_IMAGE1;
3613                                 uiReadOffsetWithinPart = 0;
3614                                 eISOWritePart = ISO_IMAGE2;
3615                                 uiWriteOffsetWithinPart = 0;
3616                                 IsThisHeaderSector = TRUE;
3617                         } else {
3618                                 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3619                                 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
3620
3621                                 if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
3622                                         eISOReadPart = ISO_IMAGE1_PART2;
3623                                         uiReadOffsetWithinPart = 0;
3624                                 }
3625
3626                                 if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
3627                                         eISOReadPart = ISO_IMAGE1_PART3;
3628                                         uiReadOffsetWithinPart = 0;
3629                                 }
3630
3631                                 if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
3632                                         eISOWritePart = ISO_IMAGE2_PART2;
3633                                         uiWriteOffsetWithinPart = 0;
3634                                 }
3635
3636                                 if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
3637                                         eISOWritePart = ISO_IMAGE2_PART3;
3638                                         uiWriteOffsetWithinPart = 0;
3639                                 }
3640                         }
3641
3642                         Status = BcmFlash2xBulkRead(Adapter,
3643                                                 (PUINT)Buff,
3644                                                 eISOReadPart,
3645                                                 uiReadOffsetWithinPart,
3646                                                 Adapter->uiSectorSize);
3647                         if (Status) {
3648                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
3649                                 break;
3650                         }
3651
3652                         if (IsThisHeaderSector == TRUE) {
3653                                 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
3654                                 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
3655
3656                                 for (i = 0; i < MAX_RW_SIZE; i++)
3657                                         *(Buff + sigOffset + i) = 0xFF;
3658                         }
3659                         Adapter->bHeaderChangeAllowed = TRUE;
3660                         Status = BcmFlash2xBulkWrite(Adapter,
3661                                                 (PUINT)Buff,
3662                                                 eISOWritePart,
3663                                                 uiWriteOffsetWithinPart,
3664                                                 Adapter->uiSectorSize,
3665                                                 TRUE);
3666                         if (Status) {
3667                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
3668                                 break;
3669                         }
3670
3671                         Adapter->bHeaderChangeAllowed = FALSE;
3672                         if (IsThisHeaderSector == TRUE) {
3673                                 WriteToFlashWithoutSectorErase(Adapter,
3674                                                         SigBuff,
3675                                                         eISOWritePart,
3676                                                         sigOffset,
3677                                                         MAX_RW_SIZE);
3678                                 IsThisHeaderSector = FALSE;
3679                         }
3680                         /* subtracting the written Data */
3681                         uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
3682                 }
3683         }
3684
3685         if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) {
3686                 eISOReadPart = ISO_IMAGE2;
3687                 eISOWritePart = ISO_IMAGE1;
3688                 uiReadOffsetWithinPart = 0;
3689                 uiWriteOffsetWithinPart = 0;
3690
3691                 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
3692                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
3693                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
3694                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
3695                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
3696                         (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3697
3698                 if (uiTotalDataToCopy < ISOLength) {
3699                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3700                         Status = STATUS_FAILURE;
3701                         goto out;
3702                 }
3703
3704                 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
3705                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
3706                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
3707                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
3708                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
3709                         (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3710
3711                 if (uiTotalDataToCopy < ISOLength) {
3712                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
3713                         Status = STATUS_FAILURE;
3714                         goto out;
3715                 }
3716
3717                 uiTotalDataToCopy = ISOLength;
3718
3719                 CorruptISOSig(Adapter, ISO_IMAGE1);
3720
3721                 while (uiTotalDataToCopy) {
3722                         if (uiTotalDataToCopy == Adapter->uiSectorSize) {
3723                                 /* Setting for write of first sector. First sector is assumed to be written in last */
3724                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
3725                                 eISOReadPart = ISO_IMAGE2;
3726                                 uiReadOffsetWithinPart = 0;
3727                                 eISOWritePart = ISO_IMAGE1;
3728                                 uiWriteOffsetWithinPart = 0;
3729                                 IsThisHeaderSector = TRUE;
3730                         } else {
3731                                 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3732                                 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
3733
3734                                 if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
3735                                         eISOReadPart = ISO_IMAGE2_PART2;
3736                                         uiReadOffsetWithinPart = 0;
3737                                 }
3738
3739                                 if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
3740                                         eISOReadPart = ISO_IMAGE2_PART3;
3741                                         uiReadOffsetWithinPart = 0;
3742                                 }
3743
3744                                 if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
3745                                         eISOWritePart = ISO_IMAGE1_PART2;
3746                                         uiWriteOffsetWithinPart = 0;
3747                                 }
3748
3749                                 if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
3750                                         eISOWritePart = ISO_IMAGE1_PART3;
3751                                         uiWriteOffsetWithinPart = 0;
3752                                 }
3753                         }
3754
3755                         Status = BcmFlash2xBulkRead(Adapter,
3756                                                 (PUINT)Buff,
3757                                                 eISOReadPart,
3758                                                 uiReadOffsetWithinPart,
3759                                                 Adapter->uiSectorSize);
3760                         if (Status) {
3761                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
3762                                 break;
3763                         }
3764
3765                         if (IsThisHeaderSector == TRUE) {
3766                                 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
3767                                 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
3768
3769                                 for (i = 0; i < MAX_RW_SIZE; i++)
3770                                         *(Buff + sigOffset + i) = 0xFF;
3771                         }
3772                         Adapter->bHeaderChangeAllowed = TRUE;
3773                         Status = BcmFlash2xBulkWrite(Adapter,
3774                                                 (PUINT)Buff,
3775                                                 eISOWritePart,
3776                                                 uiWriteOffsetWithinPart,
3777                                                 Adapter->uiSectorSize,
3778                                                 TRUE);
3779                         if (Status) {
3780                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
3781                                 break;
3782                         }
3783
3784                         Adapter->bHeaderChangeAllowed = FALSE;
3785                         if (IsThisHeaderSector == TRUE) {
3786                                 WriteToFlashWithoutSectorErase(Adapter,
3787                                                         SigBuff,
3788                                                         eISOWritePart,
3789                                                         sigOffset,
3790                                                         MAX_RW_SIZE);
3791
3792                                 IsThisHeaderSector = FALSE;
3793                         }
3794
3795                         /* subtracting the written Data */
3796                         uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
3797                 }
3798         }
3799 out:
3800         kfree(Buff);
3801
3802         return Status;
3803 }
3804
3805 /*
3806  * BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
3807  * It will corrupt the sig, if Section is writable, by making first bytes as zero.
3808  * @Adapater :- Bcm Driver Private Data Structure
3809  * @eFlash2xSectionVal :- Flash section val which has header
3810  *
3811  * Return Value :-
3812  *      Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
3813  *      Failure :-Return negative error code
3814  */
3815
3816 int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
3817 {
3818         int Status = STATUS_SUCCESS;
3819
3820         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal);
3821
3822         if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) {
3823                 Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
3824         } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) {
3825                 Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
3826         } else {
3827                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal);
3828                 return STATUS_SUCCESS;
3829         }
3830         return Status;
3831 }
3832
3833 /*
3834  *BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
3835  *                                        header and  Write Permission.
3836  * @Adapater :- Bcm Driver Private Data Structure
3837  * @eFlashSectionVal :- Flash section val which has header
3838  *
3839  * Return Value :-
3840  *      Success :- If Section is present and writable write the sig and return STATUS_SUCCESS
3841  *      Failure :-Return negative error code
3842  */
3843
3844 int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
3845 {
3846         unsigned int uiSignature = 0;
3847         unsigned int uiOffset = 0;
3848
3849         /* DSD_HEADER dsdHeader = {0}; */
3850         if (Adapter->bSigCorrupted == FALSE) {
3851                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n");
3852                 return STATUS_SUCCESS;
3853         }
3854
3855         if (Adapter->bAllDSDWriteAllow == FALSE) {
3856                 if (IsSectionWritable(Adapter, eFlashSectionVal) == FALSE) {
3857                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature");
3858                         return SECTOR_IS_NOT_WRITABLE;
3859                 }
3860         }
3861
3862         if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) {
3863                 uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER);
3864                 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader;
3865
3866                 uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber);
3867
3868                 if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
3869                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig");
3870                         return STATUS_FAILURE;
3871                 }
3872         } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) {
3873                 uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
3874                 /* uiOffset = 0; */
3875                 uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);
3876                 if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
3877                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig");
3878                         return STATUS_FAILURE;
3879                 }
3880         } else {
3881                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
3882                 return STATUS_FAILURE;
3883         }
3884
3885         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature");
3886
3887         Adapter->bHeaderChangeAllowed = TRUE;
3888         Adapter->bSigCorrupted = FALSE;
3889         BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE);
3890         Adapter->bHeaderChangeAllowed = FALSE;
3891
3892         return STATUS_SUCCESS;
3893 }
3894
3895 /*
3896  * validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
3897  *                                                    if requested Bytes goes beyond the Requested section, it reports error.
3898  * @Adapater :- Bcm Driver Private Data Structure
3899  * @psFlash2xReadWrite :-Flash2x Read/write structure pointer
3900  *
3901  * Return values:-Return TRUE is request is valid else FALSE.
3902  */
3903
3904 int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite)
3905 {
3906         unsigned int uiNumOfBytes = 0;
3907         unsigned int uiSectStartOffset = 0;
3908         unsigned int uiSectEndOffset = 0;
3909
3910         uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
3911
3912         if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) {
3913                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exixt in Flash", psFlash2xReadWrite->Section);
3914                 return FALSE;
3915         }
3916         uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section);
3917         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section);
3918         if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) {
3919                 if (psFlash2xReadWrite->Section == ISO_IMAGE1) {
3920                         uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) -
3921                                 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) +
3922                                 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) -
3923                                 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) +
3924                                 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) -
3925                                 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3);
3926                 } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) {
3927                         uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) -
3928                                 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) +
3929                                 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) -
3930                                 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART2) +
3931                                 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART3) -
3932                                 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3);
3933                 }
3934
3935                 /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset
3936                  * it should be added in startoffset. so that check done in last of this function can be valued.
3937                  */
3938                 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset;
3939
3940                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset);
3941         } else
3942                 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section);
3943
3944         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset);
3945
3946         /* Checking the boundary condition */
3947         if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
3948                 return TRUE;
3949         else {
3950                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
3951                 return FALSE;
3952         }
3953 }
3954
3955 /*
3956  * IsFlash2x :- check for Flash 2.x
3957  * Adapater :- Bcm Driver Private Data Structure
3958  *
3959  * Return value:-
3960  *      return TRUE if flah2.x of hgher version else return false.
3961  */
3962
3963 int IsFlash2x(struct bcm_mini_adapter *Adapter)
3964 {
3965         if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
3966                 return TRUE;
3967         else
3968                 return FALSE;
3969 }
3970
3971 /*
3972  * GetFlashBaseAddr :- Calculate the Flash Base address
3973  * @Adapater :- Bcm Driver Private Data Structure
3974  *
3975  * Return Value:-
3976  *      Success :- Base Address of the Flash
3977  */
3978
3979 static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
3980 {
3981         unsigned int uiBaseAddr = 0;
3982
3983         if (Adapter->bDDRInitDone) {
3984                 /*
3985                  * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3986                  * In case of Raw Read... use the default value
3987                  */
3988                 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
3989                         !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
3990                         uiBaseAddr = Adapter->uiFlashBaseAdd;
3991                 else
3992                         uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
3993         } else {
3994                 /*
3995                  * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3996                  * In case of Raw Read... use the default value
3997                  */
3998                 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
3999                         !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
4000                         uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4001                 else
4002                         uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4003         }
4004
4005         return uiBaseAddr;
4006 }
4007
4008 /*
4009  * BcmCopySection :- This API is used to copy the One section in another. Both section should
4010  *                                  be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
4011  *
4012  * @Adapater :- Bcm Driver Private Data Structure
4013  * @SrcSection :- Source section From where data has to be copied
4014  * @DstSection :- Destination section to which data has to be copied
4015  * @offset :- Offset from/to  where data has to be copied from one section to another.
4016  * @numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
4017  *                           in case of numofBytes  equal zero complete section will be copied.
4018  * Return Values-
4019  *      Success : Return STATUS_SUCCESS
4020  *      Faillure :- return negative error code
4021  */
4022
4023 int BcmCopySection(struct bcm_mini_adapter *Adapter,
4024                 enum bcm_flash2x_section_val SrcSection,
4025                 enum bcm_flash2x_section_val DstSection,
4026                 unsigned int offset,
4027                 unsigned int numOfBytes)
4028 {
4029         unsigned int BuffSize = 0;
4030         unsigned int BytesToBeCopied = 0;
4031         PUCHAR pBuff = NULL;
4032         int Status = STATUS_SUCCESS;
4033
4034         if (SrcSection == DstSection) {
4035                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again");
4036                 return -EINVAL;
4037         }
4038
4039         if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) {
4040                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection");
4041                 return -EINVAL;
4042         }
4043
4044         if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) {
4045                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection");
4046                 return -EINVAL;
4047         }
4048
4049         /* if offset zero means have to copy complete secton */
4050         if (numOfBytes == 0) {
4051                 numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection)
4052                         - BcmGetSectionValStartOffset(Adapter, SrcSection);
4053
4054                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes);
4055         }
4056
4057         if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection)
4058                 - BcmGetSectionValStartOffset(Adapter, SrcSection)) {
4059                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
4060                                 offset, numOfBytes);
4061                 return -EINVAL;
4062         }
4063
4064         if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection)
4065                 - BcmGetSectionValStartOffset(Adapter, DstSection)) {
4066                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
4067                                 offset, numOfBytes);
4068                 return -EINVAL;
4069         }
4070
4071         if (numOfBytes > Adapter->uiSectorSize)
4072                 BuffSize = Adapter->uiSectorSize;
4073         else
4074                 BuffSize = numOfBytes;
4075
4076         pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL);
4077         if (!pBuff) {
4078                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. ");
4079                 return -ENOMEM;
4080         }
4081
4082         BytesToBeCopied = Adapter->uiSectorSize;
4083         if (offset % Adapter->uiSectorSize)
4084                 BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
4085         if (BytesToBeCopied > numOfBytes)
4086                 BytesToBeCopied = numOfBytes;
4087
4088         Adapter->bHeaderChangeAllowed = TRUE;
4089
4090         do {
4091                 Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied);
4092                 if (Status) {
4093                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied);
4094                         break;
4095                 }
4096                 Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, FALSE);
4097                 if (Status) {
4098                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied);
4099                         break;
4100                 }
4101                 offset = offset + BytesToBeCopied;
4102                 numOfBytes = numOfBytes - BytesToBeCopied;
4103                 if (numOfBytes) {
4104                         if (numOfBytes > Adapter->uiSectorSize)
4105                                 BytesToBeCopied = Adapter->uiSectorSize;
4106                         else
4107                                 BytesToBeCopied = numOfBytes;
4108                 }
4109         } while (numOfBytes > 0);
4110
4111         kfree(pBuff);
4112         Adapter->bHeaderChangeAllowed = FALSE;
4113
4114         return Status;
4115 }
4116
4117 /*
4118  * SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
4119  * @Adapater :- Bcm Driver Private Data Structure
4120  * @pBuff :- Data buffer that has to be written in sector having the header map.
4121  * @uiOffset :- Flash offset that has to be written.
4122  *
4123  * Return value :-
4124  *      Success :- On success return STATUS_SUCCESS
4125  *      Faillure :- Return negative error code
4126  */
4127
4128 int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset)
4129 {
4130         unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0;
4131         BOOLEAN bHasHeader = FALSE;
4132         PUCHAR pTempBuff = NULL;
4133         unsigned int uiSectAlignAddr = 0;
4134         unsigned int sig = 0;
4135
4136         /* making the offset sector aligned */
4137         uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4138
4139         if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) ||
4140                 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) ||
4141                 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) {
4142                 /* offset from the sector boundary having the header map */
4143                 offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
4144                 HeaderSizeToProtect = sizeof(DSD_HEADER);
4145                 bHasHeader = TRUE;
4146         }
4147
4148         if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) ||
4149                 uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) {
4150                 offsetToProtect = 0;
4151                 HeaderSizeToProtect = sizeof(ISO_HEADER);
4152                 bHasHeader = TRUE;
4153         }
4154         /* If Header is present overwrite passed buffer with this */
4155         if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) {
4156                 pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL);
4157                 if (!pTempBuff) {
4158                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed");
4159                         return -ENOMEM;
4160                 }
4161                 /* Read header */
4162                 BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect);
4163                 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect);
4164                 /* Replace Buffer content with Header */
4165                 memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect);
4166
4167                 kfree(pTempBuff);
4168         }
4169         if (bHasHeader && Adapter->bSigCorrupted) {
4170                 sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber)));
4171                 sig = ntohl(sig);
4172                 if ((sig & 0xFF000000) != CORRUPTED_PATTERN) {
4173                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore");
4174                         Adapter->bSigCorrupted = FALSE;
4175                         return STATUS_SUCCESS;
4176                 }
4177                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig);
4178                 *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER);
4179                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only");
4180                 Adapter->bSigCorrupted = FALSE;
4181         }
4182
4183         return STATUS_SUCCESS;
4184 }
4185
4186 /*
4187  * BcmDoChipSelect : This will selcet the appropriate chip for writing.
4188  * @Adapater :- Bcm Driver Private Data Structure
4189  *
4190  * OutPut:-
4191  *      Select the Appropriate chip and retrn status Success
4192  */
4193 static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset)
4194 {
4195         unsigned int FlashConfig = 0;
4196         int ChipNum = 0;
4197         unsigned int GPIOConfig = 0;
4198         unsigned int PartNum = 0;
4199
4200         ChipNum = offset / FLASH_PART_SIZE;
4201
4202         /*
4203          * Chip Select mapping to enable flash0.
4204          * To select flash 0, we have to OR with (0<<12).
4205          * ORing 0 will have no impact so not doing that part.
4206          * In future if Chip select value changes from 0 to non zero,
4207          * That needs be taken care with backward comaptibility. No worries for now.
4208          */
4209
4210         /*
4211          * SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
4212          * if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
4213          * Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
4214          * power down modes (Idle mode/shutdown mode), the values in the register will be different.
4215          */
4216
4217         if (Adapter->SelectedChip == ChipNum)
4218                 return STATUS_SUCCESS;
4219
4220         /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); */
4221         Adapter->SelectedChip = ChipNum;
4222
4223         /* bit[13..12]  will select the appropriate chip */
4224         rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4225         rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4226         {
4227                 switch (ChipNum) {
4228                 case 0:
4229                         PartNum = 0;
4230                         break;
4231                 case 1:
4232                         PartNum = 3;
4233                         GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
4234                         break;
4235                 case 2:
4236                         PartNum = 1;
4237                         GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
4238                         break;
4239                 case 3:
4240                         PartNum = 2;
4241                         GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
4242                         break;
4243                 }
4244         }
4245         /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
4246          * nothing to do... can return immediately.
4247          * ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
4248          * Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
4249          * These values are not written by host other than during CHIP_SELECT.
4250          */
4251         if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
4252                 return STATUS_SUCCESS;
4253
4254         /* clearing the bit[13..12] */
4255         FlashConfig &= 0xFFFFCFFF;
4256         FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); /* 00 */
4257
4258         wrmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4259         udelay(100);
4260
4261         wrmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4262         udelay(100);
4263
4264         return STATUS_SUCCESS;
4265 }
4266
4267 int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
4268 {
4269         unsigned int uiDSDsig = 0;
4270         /* unsigned int sigoffsetInMap = 0;
4271          * DSD_HEADER dsdHeader = {0};
4272          */
4273
4274         /* sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader; */
4275
4276         if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) {
4277                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for DSDs");
4278                 return STATUS_FAILURE;
4279         }
4280         BcmFlash2xBulkRead(Adapter,
4281                         &uiDSDsig,
4282                         dsd,
4283                         Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber),
4284                         SIGNATURE_SIZE);
4285
4286         uiDSDsig = ntohl(uiDSDsig);
4287         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig);
4288
4289         return uiDSDsig;
4290 }
4291
4292 int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
4293 {
4294         /* unsigned int priOffsetInMap = 0 ; */
4295         unsigned int uiDSDPri = STATUS_FAILURE;
4296         /* DSD_HEADER dsdHeader = {0};
4297          * priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
4298          */
4299         if (IsSectionWritable(Adapter, dsd)) {
4300                 if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) {
4301                         BcmFlash2xBulkRead(Adapter,
4302                                         &uiDSDPri,
4303                                         dsd,
4304                                         Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
4305                                         4);
4306
4307                         uiDSDPri = ntohl(uiDSDPri);
4308                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri);
4309                 }
4310         }
4311
4312         return uiDSDPri;
4313 }
4314
4315 enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
4316 {
4317         int DSDHighestPri = STATUS_FAILURE;
4318         int DsdPri = 0;
4319         enum bcm_flash2x_section_val HighestPriDSD = 0;
4320
4321         if (IsSectionWritable(Adapter, DSD2)) {
4322                 DSDHighestPri = ReadDSDPriority(Adapter, DSD2);
4323                 HighestPriDSD = DSD2;
4324         }
4325
4326         if (IsSectionWritable(Adapter, DSD1)) {
4327                 DsdPri = ReadDSDPriority(Adapter, DSD1);
4328                 if (DSDHighestPri  < DsdPri) {
4329                         DSDHighestPri = DsdPri;
4330                         HighestPriDSD = DSD1;
4331                 }
4332         }
4333
4334         if (IsSectionWritable(Adapter, DSD0)) {
4335                 DsdPri = ReadDSDPriority(Adapter, DSD0);
4336                 if (DSDHighestPri  < DsdPri) {
4337                         DSDHighestPri = DsdPri;
4338                         HighestPriDSD = DSD0;
4339                 }
4340         }
4341         if (HighestPriDSD)
4342                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest DSD :%x , and its  Pri :%x", HighestPriDSD, DSDHighestPri);
4343
4344         return  HighestPriDSD;
4345 }
4346
4347 int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
4348 {
4349         unsigned int uiISOsig = 0;
4350         /* unsigned int sigoffsetInMap = 0;
4351          * ISO_HEADER ISOHeader = {0};
4352          * sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
4353          */
4354         if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) {
4355                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs");
4356                 return STATUS_FAILURE;
4357         }
4358         BcmFlash2xBulkRead(Adapter,
4359                         &uiISOsig,
4360                         iso,
4361                         0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber),
4362                         SIGNATURE_SIZE);
4363
4364         uiISOsig = ntohl(uiISOsig);
4365         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig);
4366
4367         return uiISOsig;
4368 }
4369
4370 int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
4371 {
4372         unsigned int ISOPri = STATUS_FAILURE;
4373         if (IsSectionWritable(Adapter, iso)) {
4374                 if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) {
4375                         BcmFlash2xBulkRead(Adapter,
4376                                         &ISOPri,
4377                                         iso,
4378                                         0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
4379                                         4);
4380
4381                         ISOPri = ntohl(ISOPri);
4382                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri);
4383                 }
4384         }
4385
4386         return ISOPri;
4387 }
4388
4389 enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
4390 {
4391         int ISOHighestPri = STATUS_FAILURE;
4392         int ISOPri = 0;
4393         enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL;
4394
4395         if (IsSectionWritable(Adapter, ISO_IMAGE2)) {
4396                 ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2);
4397                 HighestPriISO = ISO_IMAGE2;
4398         }
4399
4400         if (IsSectionWritable(Adapter, ISO_IMAGE1)) {
4401                 ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1);
4402                 if (ISOHighestPri  < ISOPri) {
4403                         ISOHighestPri = ISOPri;
4404                         HighestPriISO = ISO_IMAGE1;
4405                 }
4406         }
4407         if (HighestPriISO)
4408                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest ISO :%x and its Pri :%x", HighestPriISO, ISOHighestPri);
4409
4410         return HighestPriISO;
4411 }
4412
4413 int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
4414                                 PUINT pBuff,
4415                                 enum bcm_flash2x_section_val eFlash2xSectionVal,
4416                                 unsigned int uiOffset,
4417                                 unsigned int uiNumBytes)
4418 {
4419         #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
4420                 unsigned int uiTemp = 0, value = 0;
4421                 unsigned int i = 0;
4422                 unsigned int uiPartOffset = 0;
4423         #endif
4424         unsigned int uiStartOffset = 0;
4425         /* Adding section start address */
4426         int Status = STATUS_SUCCESS;
4427         PUCHAR pcBuff = (PUCHAR)pBuff;
4428
4429         if (uiNumBytes % Adapter->ulFlashWriteSize) {
4430                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
4431                 return STATUS_FAILURE;
4432         }
4433
4434         uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
4435
4436         if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
4437                 return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
4438
4439         uiOffset = uiOffset + uiStartOffset;
4440
4441         #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
4442                 Status = bcmflash_raw_writenoerase((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), pcBuff, uiNumBytes);
4443         #else
4444                 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4445                 value = 0;
4446                 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
4447
4448                 Adapter->SelectedChip = RESET_CHIP_SELECT;
4449                 BcmDoChipSelect(Adapter, uiOffset);
4450                 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
4451
4452                 for (i = 0 ; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
4453                         if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
4454                                 Status = flashByteWrite(Adapter, uiPartOffset, pcBuff);
4455                         else
4456                                 Status = flashWrite(Adapter, uiPartOffset, pcBuff);
4457
4458                         if (Status != STATUS_SUCCESS)
4459                                 break;
4460
4461                         pcBuff = pcBuff + Adapter->ulFlashWriteSize;
4462                         uiPartOffset = uiPartOffset +  Adapter->ulFlashWriteSize;
4463                 }
4464                 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4465                 Adapter->SelectedChip = RESET_CHIP_SELECT;
4466         #endif
4467
4468         return Status;
4469 }
4470
4471 BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
4472 {
4473         BOOLEAN SectionPresent = FALSE;
4474
4475         switch (section) {
4476         case ISO_IMAGE1:
4477                 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
4478                         (IsNonCDLessDevice(Adapter) == FALSE))
4479                         SectionPresent = TRUE;
4480                 break;
4481         case ISO_IMAGE2:
4482                 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
4483                         (IsNonCDLessDevice(Adapter) == FALSE))
4484                         SectionPresent = TRUE;
4485                 break;
4486         case DSD0:
4487                 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
4488                         SectionPresent = TRUE;
4489                 break;
4490         case DSD1:
4491                 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
4492                         SectionPresent = TRUE;
4493                 break;
4494         case DSD2:
4495                 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
4496                         SectionPresent = TRUE;
4497                 break;
4498         case VSA0:
4499                 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
4500                         SectionPresent = TRUE;
4501                 break;
4502         case VSA1:
4503                 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
4504                         SectionPresent = TRUE;
4505                 break;
4506         case VSA2:
4507                 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
4508                         SectionPresent = TRUE;
4509                 break;
4510         case SCSI:
4511                 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
4512                         SectionPresent = TRUE;
4513                 break;
4514         case CONTROL_SECTION:
4515                 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
4516                         SectionPresent = TRUE;
4517                 break;
4518         default:
4519                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
4520                 SectionPresent =  FALSE;
4521         }
4522
4523         return SectionPresent;
4524 }
4525
4526 int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
4527 {
4528         int offset = STATUS_FAILURE;
4529         int Status = FALSE;
4530
4531         if (IsSectionExistInFlash(Adapter, Section) == FALSE) {
4532                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exixt", Section);
4533                 return FALSE;
4534         }
4535
4536         offset = BcmGetSectionValStartOffset(Adapter, Section);
4537         if (offset == INVALID_OFFSET) {
4538                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exixt", Section);
4539                 return FALSE;
4540         }
4541
4542         if (IsSectionExistInVendorInfo(Adapter, Section))
4543                 return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
4544
4545         Status = IsOffsetWritable(Adapter, offset);
4546         return Status;
4547 }
4548
4549 static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
4550 {
4551         PUCHAR pBuff = NULL;
4552         unsigned int sig = 0;
4553         unsigned int uiOffset = 0;
4554         unsigned int BlockStatus = 0;
4555         unsigned int uiSectAlignAddr = 0;
4556
4557         Adapter->bSigCorrupted = FALSE;
4558         if (Adapter->bAllDSDWriteAllow == FALSE) {
4559                 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
4560                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
4561                         return SECTOR_IS_NOT_WRITABLE;
4562                 }
4563         }
4564
4565         pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
4566         if (!pBuff) {
4567                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4568                 return -ENOMEM;
4569         }
4570
4571         uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER);
4572         uiOffset -= MAX_RW_SIZE;
4573
4574         BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
4575
4576         sig = *((PUINT)(pBuff + 12));
4577         sig = ntohl(sig);
4578         BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
4579         /* Now corrupting the sig by corrupting 4th last Byte. */
4580         *(pBuff + 12) = 0;
4581
4582         if (sig == DSD_IMAGE_MAGIC_NUMBER) {
4583                 Adapter->bSigCorrupted = TRUE;
4584                 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) {
4585                         uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4586                         BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
4587
4588                         WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal,
4589                                                 (uiOffset + 12), BYTE_WRITE_SUPPORT);
4590                         if (BlockStatus) {
4591                                 BcmRestoreBlockProtectStatus(Adapter, BlockStatus);
4592                                 BlockStatus = 0;
4593                         }
4594                 } else {
4595                         WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4596                                                 uiOffset, MAX_RW_SIZE);
4597                 }
4598         } else {
4599                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
4600                 kfree(pBuff);
4601
4602                 return STATUS_FAILURE;
4603         }
4604
4605         kfree(pBuff);
4606         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
4607
4608         return STATUS_SUCCESS;
4609 }
4610
4611 static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
4612 {
4613         PUCHAR pBuff = NULL;
4614         unsigned int sig = 0;
4615         unsigned int uiOffset = 0;
4616
4617         Adapter->bSigCorrupted = FALSE;
4618
4619         if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
4620                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
4621                 return SECTOR_IS_NOT_WRITABLE;
4622         }
4623
4624         pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
4625         if (!pBuff) {
4626                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4627                 return -ENOMEM;
4628         }
4629
4630         uiOffset = 0;
4631
4632         BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
4633
4634         sig = *((PUINT)pBuff);
4635         sig = ntohl(sig);
4636
4637         /* corrupt signature */
4638         *pBuff = 0;
4639
4640         if (sig == ISO_IMAGE_MAGIC_NUMBER) {
4641                 Adapter->bSigCorrupted = TRUE;
4642                 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4643                                         uiOffset, Adapter->ulFlashWriteSize);
4644         } else {
4645                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
4646                 kfree(pBuff);
4647
4648                 return STATUS_FAILURE;
4649         }
4650
4651         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
4652         BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
4653
4654         kfree(pBuff);
4655         return STATUS_SUCCESS;
4656 }
4657
4658 BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter)
4659 {
4660         if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
4661                 return TRUE;
4662         else
4663                 return FALSE;
4664 }