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