Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[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 #ifdef BCM_SHM_INTERFACE
2646 #ifdef FLASH_DIRECT_ACCESS
2647         unsigned int data,data1,data2 = 1;
2648         wrm(ps_adapter, PAD_SELECT_REGISTER, &data2, 4);
2649         data1 = rdm(ps_adapter,SYS_CFG,&data,4);
2650         data1 = rdm(ps_adapter,SYS_CFG,&data,4);
2651         data2 = (data | 0x80 | 0x8000);
2652         wrm(ps_adapter,SYS_CFG, &data2,4); // over-write as Flash boot mode
2653 #endif
2654         ps_adapter->eNVMType = NVM_FLASH;
2655 #else
2656         BcmValidateNvmType(ps_adapter);
2657         BcmInitEEPROMQueues(ps_adapter);
2658 #endif
2659
2660         if(ps_adapter->eNVMType == NVM_AUTODETECT)
2661         {
2662                 ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
2663                 if(ps_adapter->eNVMType == NVM_UNKNOWN)
2664                 {
2665                         BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
2666                 }
2667         }
2668         else if(ps_adapter->eNVMType == NVM_FLASH)
2669         {
2670                 BcmGetFlashCSInfo(ps_adapter);
2671         }
2672
2673         BcmGetNvmSize(ps_adapter);
2674
2675         return STATUS_SUCCESS;
2676 }
2677 /***************************************************************************/
2678 /*BcmGetNvmSize : set the EEPROM or flash size in Adapter.
2679 *
2680 *Input Parameter:
2681 *               Adapter data structure
2682 *Return Value :
2683 *               0. means sucess;
2684 */
2685 /***************************************************************************/
2686
2687 INT BcmGetNvmSize(PMINI_ADAPTER Adapter)
2688 {
2689         if(Adapter->eNVMType == NVM_EEPROM)
2690         {
2691                 Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
2692         }
2693         else if(Adapter->eNVMType == NVM_FLASH)
2694         {
2695                 Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
2696         }
2697         return 0;
2698 }
2699
2700 //-----------------------------------------------------------------------------
2701 // Procedure:   BcmValidateNvm
2702 //
2703 // Description: Validates the NVM Type option selected against the device
2704 //
2705 // Arguments:
2706 //              Adapter    - ptr to Adapter object instance
2707 //
2708 // Returns:
2709 //              <VOID>
2710 //-----------------------------------------------------------------------------
2711 VOID BcmValidateNvmType(PMINI_ADAPTER Adapter)
2712 {
2713
2714         //
2715         // if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
2716         // Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
2717         // So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
2718         //
2719
2720         if(Adapter->eNVMType == NVM_FLASH &&
2721                 Adapter->chip_id < 0xBECE3300)
2722         {
2723                 Adapter->eNVMType = NVM_AUTODETECT;
2724         }
2725 }
2726 //-----------------------------------------------------------------------------
2727 // Procedure:   BcmReadFlashRDID
2728 //
2729 // Description: Reads ID from Serial Flash
2730 //
2731 // Arguments:
2732 //              Adapter    - ptr to Adapter object instance
2733 //
2734 // Returns:
2735 //              Flash ID
2736 //-----------------------------------------------------------------------------
2737 static ULONG BcmReadFlashRDID(PMINI_ADAPTER Adapter)
2738 {
2739         ULONG ulRDID = 0;
2740         UINT value;
2741 //
2742 // Read ID Instruction.
2743 //
2744         value = (FLASH_CMD_READ_ID<<24);
2745         wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value));
2746
2747 //Delay
2748         udelay(10);
2749 //
2750 // Read SPI READQ REG. The output will be WWXXYYZZ.
2751 // The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
2752 //
2753         rdmalt(Adapter, FLASH_SPI_READQ_REG,(PUINT)&ulRDID, sizeof(ulRDID));
2754
2755         return (ulRDID >>8);
2756
2757
2758 }
2759
2760 INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
2761 {
2762         if(psAdapter == NULL)
2763         {
2764                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
2765                 return -EINVAL;
2766         }
2767         psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL);
2768         if(psAdapter->psFlashCSInfo == NULL)
2769         {
2770                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 1.x");
2771                 return -ENOMEM;
2772         }
2773
2774         psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL);
2775         if(psAdapter->psFlash2xCSInfo == NULL)
2776         {
2777                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x");
2778                 bcm_kfree(psAdapter->psFlashCSInfo);
2779                 return -ENOMEM;
2780         }
2781
2782         psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL);
2783         if(psAdapter->psFlash2xVendorInfo == NULL)
2784         {
2785                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x");
2786                 bcm_kfree(psAdapter->psFlashCSInfo);
2787                 bcm_kfree(psAdapter->psFlash2xCSInfo);
2788                 return -ENOMEM;
2789         }
2790
2791         return STATUS_SUCCESS;
2792 }
2793
2794 INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
2795 {
2796         if(psAdapter == NULL)
2797         {
2798                 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL");
2799                 return -EINVAL;
2800         }
2801         bcm_kfree(psAdapter->psFlashCSInfo);
2802         bcm_kfree(psAdapter->psFlash2xCSInfo);
2803         bcm_kfree(psAdapter->psFlash2xVendorInfo);
2804         return STATUS_SUCCESS ;
2805 }
2806
2807 static INT      BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,PMINI_ADAPTER Adapter)
2808 {
2809         UINT Index = 0;
2810     BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
2811         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is  :%x", (psFlash2xCSInfo->MagicNumber));
2812         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2813         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2814         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
2815         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
2816         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
2817         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
2818         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware  :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware ));
2819         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
2820         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
2821         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
2822         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
2823         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
2824         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
2825         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
2826         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
2827         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
2828         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
2829         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
2830         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
2831         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
2832         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
2833         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
2834         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
2835         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
2836         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
2837         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
2838         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
2839         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
2840         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
2841         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
2842         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
2843         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End  :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
2844         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
2845         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
2846         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
2847         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
2848         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
2849         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
2850         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
2851         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
2852         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
2853         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
2854         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
2855         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
2856         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
2857         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
2858         for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
2859         {
2860                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
2861                                 (psFlash2xCSInfo->SectorAccessBitMap[Index]));
2862         }
2863
2864         return STATUS_SUCCESS;
2865 }
2866
2867
2868 static INT      ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo)
2869 {
2870         UINT Index = 0;
2871         psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
2872         psFlash2xCSInfo->FlashLayoutVersion= ntohl(psFlash2xCSInfo->FlashLayoutVersion);
2873         //psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion);
2874         psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
2875         psFlash2xCSInfo->SCSIFirmwareVersion =ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
2876         psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
2877         psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
2878         psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware );
2879         psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
2880         psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
2881         psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
2882         psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
2883         psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
2884         psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
2885         psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
2886         psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
2887         psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
2888         psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
2889         psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
2890         psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
2891         psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
2892         psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
2893         psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
2894         psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
2895         psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
2896         psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
2897         psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
2898         psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
2899         psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
2900         psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
2901         psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
2902         psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
2903         psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
2904         psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
2905         psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
2906         psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
2907         psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
2908         psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
2909         psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
2910         psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
2911         psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
2912         psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
2913         psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
2914         psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
2915         psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
2916         psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
2917         for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
2918         {
2919                         psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
2920         }
2921         return STATUS_SUCCESS;
2922 }
2923
2924 static INT      ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo)
2925 {
2926         //UINT Index = 0;
2927         psFlashCSInfo->MagicNumber                                                      =ntohl(psFlashCSInfo->MagicNumber);
2928         psFlashCSInfo->FlashLayoutVersion                                       =ntohl(psFlashCSInfo->FlashLayoutVersion);
2929         psFlashCSInfo->ISOImageVersion                                          = ntohl(psFlashCSInfo->ISOImageVersion);
2930         //won't convert according to old assumption
2931         psFlashCSInfo->SCSIFirmwareVersion =(psFlashCSInfo->SCSIFirmwareVersion);
2932
2933         psFlashCSInfo->OffsetFromZeroForPart1ISOImage           = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
2934         psFlashCSInfo->OffsetFromZeroForScsiFirmware        = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
2935         psFlashCSInfo->SizeOfScsiFirmware                   = ntohl(psFlashCSInfo->SizeOfScsiFirmware );
2936         psFlashCSInfo->OffsetFromZeroForPart2ISOImage       = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
2937         psFlashCSInfo->OffsetFromZeroForCalibrationStart    = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2938         psFlashCSInfo->OffsetFromZeroForCalibrationEnd      = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
2939         psFlashCSInfo->OffsetFromZeroForVSAStart            = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
2940         psFlashCSInfo->OffsetFromZeroForVSAEnd              = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
2941         psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
2942         psFlashCSInfo->OffsetFromZeroForControlSectionData  = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
2943         psFlashCSInfo->CDLessInactivityTimeout                          = ntohl(psFlashCSInfo->CDLessInactivityTimeout);
2944         psFlashCSInfo->NewImageSignature                    = ntohl(psFlashCSInfo->NewImageSignature);
2945         psFlashCSInfo->FlashSectorSizeSig                   = ntohl(psFlashCSInfo->FlashSectorSizeSig);
2946         psFlashCSInfo->FlashSectorSize                      = ntohl(psFlashCSInfo->FlashSectorSize);
2947         psFlashCSInfo->FlashWriteSupportSize                = ntohl(psFlashCSInfo->FlashWriteSupportSize);
2948         psFlashCSInfo->TotalFlashSize                                   = ntohl(psFlashCSInfo->TotalFlashSize);
2949         psFlashCSInfo->FlashBaseAddr                                    = ntohl(psFlashCSInfo->FlashBaseAddr);
2950         psFlashCSInfo->FlashPartMaxSize                                 = ntohl(psFlashCSInfo->FlashPartMaxSize);
2951         psFlashCSInfo->IsCDLessDeviceBootSig                            = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
2952         psFlashCSInfo->MassStorageTimeout                               = ntohl(psFlashCSInfo->MassStorageTimeout);
2953
2954         return STATUS_SUCCESS;
2955 }
2956
2957 INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
2958 {
2959         return ( Adapter->uiVendorExtnFlag &&
2960                 (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
2961                 (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS) );
2962 }
2963
2964 static VOID UpdateVendorInfo(PMINI_ADAPTER Adapter)
2965 {
2966         B_UINT32 i = 0;
2967         UINT uiSizeSection = 0;
2968
2969         Adapter->uiVendorExtnFlag = FALSE;
2970
2971         for(i = 0;i < TOTAL_SECTIONS;i++)
2972                 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
2973
2974         if(STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
2975                 return;
2976
2977         i = 0;
2978         while(i < TOTAL_SECTIONS)
2979         {
2980                 if(!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT))
2981                 {
2982                         i++;
2983                         continue;
2984                 }
2985
2986                 Adapter->uiVendorExtnFlag = TRUE;
2987                 uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
2988                                                 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
2989
2990                 switch(i)
2991                 {
2992                 case DSD0:
2993                         if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
2994                         (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2995                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
2996                         else
2997                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
2998                         break;
2999
3000                 case DSD1:
3001                         if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
3002                         (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
3003                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
3004                         else
3005                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
3006                         break;
3007
3008                 case DSD2:
3009                         if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
3010                         (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
3011                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
3012                         else
3013                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
3014                         break;
3015                 case VSA0:
3016                         if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
3017                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
3018                         else
3019                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
3020                         break;
3021
3022                 case VSA1:
3023                         if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
3024                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
3025                         else
3026                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
3027                         break;
3028                 case VSA2:
3029                         if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
3030                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
3031                         else
3032                                 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
3033                         break;
3034
3035                 default:
3036                         break;
3037                 }
3038                 i++;
3039         }
3040
3041 }
3042
3043 //-----------------------------------------------------------------------------
3044 // Procedure:   BcmGetFlashCSInfo
3045 //
3046 // Description: Reads control structure and gets Cal section addresses.
3047 //
3048 // Arguments:
3049 //              Adapter    - ptr to Adapter object instance
3050 //
3051 // Returns:
3052 //              <VOID>
3053 //-----------------------------------------------------------------------------
3054
3055 INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter)
3056 {
3057         //FLASH_CS_INFO sFlashCsInfo = {0};
3058
3059 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
3060         UINT value;
3061 #endif
3062         UINT uiFlashLayoutMajorVersion;
3063         Adapter->uiFlashLayoutMinorVersion = 0;
3064         Adapter->uiFlashLayoutMajorVersion = 0;
3065         Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
3066
3067
3068         Adapter->uiFlashBaseAdd = 0;
3069         Adapter->ulFlashCalStart = 0;
3070         memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO));
3071         memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO));
3072
3073 #ifndef BCM_SHM_INTERFACE
3074         if(!Adapter->bDDRInitDone)
3075         {
3076                 {
3077                         value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
3078                         wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
3079                 }
3080         }
3081
3082 #endif
3083
3084         // Reading first 8 Bytes to get the Flash Layout
3085         // MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
3086         BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,8);
3087
3088         Adapter->psFlashCSInfo->FlashLayoutVersion =  ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
3089         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
3090         //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion));
3091         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is  :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));
3092
3093         if(FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber))
3094         {
3095                 uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
3096                 Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
3097         }
3098         else
3099         {
3100                 Adapter->uiFlashLayoutMinorVersion = 0;
3101                 uiFlashLayoutMajorVersion = 0;
3102         }
3103
3104         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);
3105
3106         if(uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER)
3107         {
3108                 BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,sizeof(FLASH_CS_INFO));
3109                 ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
3110                 Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);
3111
3112                 if(!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
3113                 {
3114                         Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
3115                 }
3116
3117                 if((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) &&
3118                    (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) &&
3119                    (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) &&
3120                    (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize)))
3121                 {
3122                         Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
3123                         Adapter->fpFlashWrite = flashByteWrite;
3124                         Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
3125                 }
3126                 else
3127                 {
3128                         Adapter->ulFlashWriteSize = MAX_RW_SIZE;
3129                         Adapter->fpFlashWrite = flashWrite;
3130                         Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
3131                 }
3132
3133                 BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
3134                                          (Adapter->psFlashCSInfo->FlashSectorSize));
3135
3136
3137                 Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;
3138
3139
3140         }
3141         else
3142         {
3143                 if(BcmFlash2xBulkRead(Adapter,(PUINT)Adapter->psFlash2xCSInfo,NO_SECTION_VAL,
3144                                 Adapter->ulFlashControlSectionStart,sizeof(FLASH2X_CS_INFO)))
3145                 {
3146                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure \n");
3147                         return STATUS_FAILURE;
3148                 }
3149                 ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
3150 #ifndef BCM_SHM_INTERFACE
3151                 BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter);
3152 #endif
3153                 if((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
3154                    (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
3155                    (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
3156                    (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize))
3157                 {
3158                         Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
3159                         Adapter->fpFlashWrite = flashByteWrite;
3160                         Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
3161                 }
3162                 else
3163                 {
3164                         Adapter->ulFlashWriteSize = MAX_RW_SIZE;
3165                         Adapter->fpFlashWrite = flashWrite;
3166                         Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
3167                 }
3168
3169                 BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
3170                                         Adapter->psFlash2xCSInfo->FlashSectorSize);
3171
3172                 UpdateVendorInfo(Adapter);
3173
3174                 BcmGetActiveDSD(Adapter);
3175                 BcmGetActiveISO(Adapter);
3176                 Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
3177                 Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;
3178
3179         }
3180         /*
3181         Concerns: what if CS sector size does not match with this sector size ???
3182         what is the indication of AccessBitMap  in CS in flash 2.x ????
3183         */
3184 #ifndef BCM_SHM_INTERFACE
3185         Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
3186 #endif
3187
3188         Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
3189
3190         #if 0
3191         if(FLASH_PART_SST25VF080B == Adapter->ulFlashID)
3192         {
3193         //
3194         // 1MB flash has been selected. we have to use 64K as sector size no matter what is kept in FLASH_CS.
3195         //
3196                 Adapter->uiSectorSize = 0x10000;
3197         }
3198         #endif
3199
3200         return STATUS_SUCCESS ;
3201 }
3202
3203
3204 //-----------------------------------------------------------------------------
3205 // Procedure:   BcmGetNvmType
3206 //
3207 // Description: Finds the type of NVM used.
3208 //
3209 // Arguments:
3210 //              Adapter    - ptr to Adapter object instance
3211 //
3212 // Returns:
3213 //              NVM_TYPE
3214 //
3215 //-----------------------------------------------------------------------------
3216
3217 NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter)
3218 {
3219         UINT uiData = 0;
3220
3221         BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
3222         if(uiData == BECM)
3223         {
3224                 return NVM_EEPROM;
3225         }
3226         //
3227         // Read control struct and get cal addresses before accessing the flash
3228         //
3229         BcmGetFlashCSInfo(Adapter);
3230
3231         BeceemFlashBulkRead(Adapter,&uiData,0x0 + Adapter->ulFlashCalStart,4);
3232         if(uiData == BECM)
3233         {
3234                 return NVM_FLASH;
3235         }
3236 //
3237 // even if there is no valid signature on EEPROM/FLASH find out if they really exist.
3238 // if exist select it.
3239 //
3240         if(BcmGetEEPROMSize(Adapter))
3241         {
3242                 return NVM_EEPROM;
3243         }
3244
3245 //TBD for Flash.
3246
3247
3248         return NVM_UNKNOWN;
3249 }
3250
3251 /**
3252 *       BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
3253 *       @Adapter : Drivers Private Data structure
3254 *       @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
3255 *
3256 *       Return value:-
3257 *       On success it return the start offset of the provided section val
3258 *       On Failure -returns STATUS_FAILURE
3259 **/
3260
3261 INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
3262 {
3263         /*
3264         *       Considering all the section for which end offset can be calculated or directly given
3265         *       in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
3266         *       endoffset can't be calculated or given in CS Stucture.
3267         */
3268
3269         INT SectStartOffset = 0 ;
3270
3271         SectStartOffset = INVALID_OFFSET ;
3272
3273         if(IsSectionExistInVendorInfo(Adapter,eFlashSectionVal))
3274         {
3275                 return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
3276         }
3277
3278         switch(eFlashSectionVal)
3279         {
3280                 case ISO_IMAGE1 :
3281                           if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
3282                                 (IsNonCDLessDevice(Adapter) == FALSE))
3283                                   SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3284                            break;
3285                 case ISO_IMAGE2 :
3286                                 if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
3287                                         (IsNonCDLessDevice(Adapter) == FALSE))
3288                                         SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
3289                           break;
3290                 case DSD0 :
3291                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
3292                                         SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
3293                                 break;
3294                 case DSD1 :
3295                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
3296                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
3297                                 break;
3298                 case DSD2 :
3299                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
3300                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
3301                                 break;
3302                 case VSA0 :
3303                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
3304                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
3305                                 break;
3306                 case VSA1 :
3307                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
3308                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
3309                                 break;
3310                 case VSA2 :
3311                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
3312                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
3313                                 break;
3314                 case SCSI :
3315                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
3316                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
3317                                 break;
3318                 case CONTROL_SECTION :
3319                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
3320                                         SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
3321                                 break;
3322                 case ISO_IMAGE1_PART2 :
3323                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
3324                                          SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
3325                                  break;
3326                 case ISO_IMAGE1_PART3 :
3327                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
3328                                   SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3329                                 break;
3330                 case ISO_IMAGE2_PART2 :
3331                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
3332                                          SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
3333                             break;
3334                 case ISO_IMAGE2_PART3 :
3335                           if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
3336                                   SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3337                           break;
3338                 default :
3339                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
3340                         SectStartOffset =  INVALID_OFFSET;
3341         }
3342         return SectStartOffset;
3343 }
3344
3345 /**
3346 *       BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
3347 *       @Adapter : Drivers Private Data structure
3348 *       @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
3349 *
3350 *       Return value:-
3351 *       On success it return the end offset of the provided section val
3352 *       On Failure -returns STATUS_FAILURE
3353 **/
3354
3355 INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
3356 {
3357         INT SectEndOffset = 0 ;
3358         SectEndOffset = INVALID_OFFSET;
3359
3360         if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
3361         {
3362                 return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
3363         }
3364
3365         switch(eFlash2xSectionVal)
3366         {
3367                 case ISO_IMAGE1 :
3368                          if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End!= UNINIT_PTR_IN_CS) &&
3369                                  (IsNonCDLessDevice(Adapter) == FALSE))
3370                                   SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
3371                            break;
3372                 case ISO_IMAGE2 :
3373                         if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End!= UNINIT_PTR_IN_CS) &&
3374                                 (IsNonCDLessDevice(Adapter) == FALSE))
3375                                         SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
3376                          break;
3377                 case DSD0 :
3378                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
3379                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
3380                         break;
3381                 case DSD1 :
3382                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
3383                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
3384                         break;
3385                 case DSD2 :
3386                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
3387                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
3388                         break;
3389                 case VSA0 :
3390                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
3391                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
3392                         break;
3393                 case VSA1 :
3394                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
3395                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
3396                         break;
3397                 case VSA2 :
3398                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
3399                                 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
3400                         break;
3401                 case SCSI :
3402                         if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
3403                                 SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
3404                                         (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
3405                         break;
3406                 case CONTROL_SECTION :
3407                                 //Not Clear So Putting failure. confirm and fix it.
3408                                 SectEndOffset = STATUS_FAILURE;
3409                 case ISO_IMAGE1_PART2 :
3410                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End!= UNINIT_PTR_IN_CS)
3411                                          SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
3412                                  break;
3413                 case ISO_IMAGE1_PART3 :
3414                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End!= UNINIT_PTR_IN_CS)
3415                                   SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
3416                                 break;
3417                 case ISO_IMAGE2_PART2 :
3418                                 if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
3419                                          SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
3420                             break;
3421                 case ISO_IMAGE2_PART3 :
3422                           if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End!= UNINIT_PTR_IN_CS)
3423                                   SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
3424                           break;
3425
3426                 default :
3427                         SectEndOffset = INVALID_OFFSET;
3428         }
3429         return SectEndOffset ;
3430 }
3431
3432 /*
3433 *       BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
3434 *       @Adapter :Driver Private Data Structure
3435 *       @pBuffer : Buffer where data has to be put after reading
3436 *       @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
3437 *       @uiOffsetWithinSectionVal :- Offset with in provided section
3438 *       @uiNumBytes : Number of Bytes for Read
3439 *
3440 *       Return value:-
3441 *               return true on sucess and STATUS_FAILURE on fail.
3442 */
3443
3444 INT BcmFlash2xBulkRead(
3445         PMINI_ADAPTER Adapter,
3446         PUINT pBuffer,
3447         FLASH2X_SECTION_VAL eFlash2xSectionVal,
3448         UINT uiOffsetWithinSectionVal,
3449         UINT uiNumBytes)
3450 {
3451
3452         INT Status = STATUS_SUCCESS;
3453         INT SectionStartOffset = 0;
3454         UINT uiAbsoluteOffset = 0 ;
3455         UINT uiTemp =0, value =0 ;
3456         if(Adapter == NULL)
3457         {
3458                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
3459                 return -EINVAL;
3460         }
3461         if(Adapter->device_removed )
3462         {
3463                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
3464                 return -ENODEV;
3465         }
3466
3467         //NO_SECTION_VAL means absolute offset is given.
3468         if(eFlash2xSectionVal == NO_SECTION_VAL)
3469                 SectionStartOffset = 0;
3470         else
3471                 SectionStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
3472
3473         if(SectionStartOffset == STATUS_FAILURE )
3474         {
3475                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash 2.x Map ",eFlash2xSectionVal);
3476                 return -EINVAL;
3477         }
3478
3479         if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
3480                 return vendorextnReadSection(Adapter,(PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
3481
3482         //calculating  the absolute offset from FLASH;
3483         uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
3484         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3485         value = 0;
3486         wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
3487
3488         Status= BeceemFlashBulkRead(Adapter, pBuffer,uiAbsoluteOffset,uiNumBytes) ;
3489
3490         wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3491         if(Status)
3492         {
3493                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
3494                 return Status ;
3495         }
3496
3497         return Status;
3498 }
3499
3500 /*
3501 *       BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
3502 *       @Adapter :Driver Private Data Structure
3503 *       @pBuffer : Buffer From where data has to taken for writing
3504 *       @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
3505 *       @uiOffsetWithinSectionVal :- Offset with in provided section
3506 *       @uiNumBytes : Number of Bytes for Write
3507 *
3508 *       Return value:-
3509 *               return true on sucess and STATUS_FAILURE on fail.
3510 *
3511 */
3512
3513 INT BcmFlash2xBulkWrite(
3514         PMINI_ADAPTER Adapter,
3515         PUINT pBuffer,
3516         FLASH2X_SECTION_VAL eFlash2xSectVal,
3517         UINT uiOffset,
3518         UINT uiNumBytes,
3519         UINT bVerify)
3520 {
3521
3522         INT Status      = STATUS_SUCCESS;
3523         UINT FlashSectValStartOffset = 0;
3524         UINT uiTemp = 0, value = 0;
3525         if(Adapter == NULL)
3526         {
3527                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
3528                 return -EINVAL;
3529         }
3530         if(Adapter->device_removed )
3531         {
3532                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
3533                 return -ENODEV;
3534         }
3535
3536         //NO_SECTION_VAL means absolute offset is given.
3537         if(eFlash2xSectVal == NO_SECTION_VAL)
3538                 FlashSectValStartOffset = 0;
3539         else
3540                 FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectVal);
3541
3542         if(FlashSectValStartOffset == STATUS_FAILURE )
3543         {
3544                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash Map 2.x",eFlash2xSectVal);
3545                 return -EINVAL;
3546         }
3547
3548         if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectVal))
3549                 return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
3550
3551         //calculating  the absolute offset from FLASH;
3552         uiOffset = uiOffset + FlashSectValStartOffset;
3553
3554         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3555         value = 0;
3556         wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
3557
3558         Status = BeceemFlashBulkWrite(Adapter, pBuffer,uiOffset,uiNumBytes,bVerify);
3559
3560         wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3561         if(Status)
3562         {
3563                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
3564                 return Status ;
3565         }
3566
3567         return Status;
3568
3569 }
3570
3571 /**
3572 *       ReadDSDHeader : Read the DSD map for the DSD Section val provided in Argument.
3573 *       @Adapter : Beceem Private Data Structure
3574 *       @psDSDHeader :Pointer of the buffer where header has to be read
3575 *       @dsd :value of the Dyanmic DSD like DSD0 of DSD1 or DSD2
3576 *
3577 *       Return Value:-
3578 *               if suceeds return STATUS_SUCCESS or negative error code.
3579 **/
3580 INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd)
3581 {
3582         INT Status = STATUS_SUCCESS;
3583
3584         Status =BcmFlash2xBulkRead(Adapter,
3585                                                     (PUINT)psDSDHeader,
3586                                                         dsd,
3587                                                         Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader,
3588                                                         sizeof(DSD_HEADER));
3589         if(Status == STATUS_SUCCESS)
3590         {
3591                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageMagicNumber :0X%x", ntohl(psDSDHeader->DSDImageMagicNumber));
3592                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageSize :0X%x ",ntohl(psDSDHeader->DSDImageSize));
3593                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageCRC :0X%x",ntohl(psDSDHeader->DSDImageCRC));
3594                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImagePriority :0X%x",ntohl(psDSDHeader->DSDImagePriority));
3595         }
3596         else
3597         {
3598                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DSD Header read is failed with status :%d", Status);
3599         }
3600
3601         return Status;
3602 }
3603
3604 /**
3605 *       BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
3606 *       @Adapter :-Drivers private Data Structure
3607 *
3608 *       Return Value:-
3609 *               Return STATUS_SUCESS if get sucess in setting the right DSD else negaive error code
3610 *
3611 **/
3612 INT BcmGetActiveDSD(PMINI_ADAPTER Adapter)
3613 {
3614         FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
3615
3616         uiHighestPriDSD = getHighestPriDSD(Adapter);
3617         Adapter->eActiveDSD = uiHighestPriDSD;
3618
3619         if(DSD0  == uiHighestPriDSD)
3620                 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
3621         if(DSD1 == uiHighestPriDSD)
3622                 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
3623         if(DSD2 == uiHighestPriDSD)
3624                 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
3625         if(Adapter->eActiveDSD)
3626                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
3627         if(Adapter->eActiveDSD == 0)
3628         {
3629                 //if No DSD gets Active, Make Active the DSD with WR  permission
3630                 if(IsSectionWritable(Adapter,DSD2))
3631                 {
3632                         Adapter->eActiveDSD = DSD2;
3633                         Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
3634                 }
3635                 else if(IsSectionWritable(Adapter,DSD1))
3636                 {
3637                         Adapter->eActiveDSD = DSD1;
3638                         Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
3639                 }
3640                 else if(IsSectionWritable(Adapter,DSD0))
3641                 {
3642                         Adapter->eActiveDSD = DSD0;
3643                         Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
3644                 }
3645         }
3646
3647         return STATUS_SUCCESS;
3648 }
3649
3650 /**
3651 *       ReadISOUnReservedBytes : Read the ISO map for the ISO Section val provided in Argument.
3652 *       @Adapter : Driver Private Data Structure
3653 *       @psISOHeader :Pointer of the location where header has to be read
3654 *       @IsoImage :value of the Dyanmic ISO like ISO_IMAGE1 of ISO_IMAGE2
3655 *
3656 *       Return Value:-
3657 *               if suceeds return STATUS_SUCCESS or negative error code.
3658 **/
3659
3660 INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage)
3661 {
3662         INT Status = STATUS_SUCCESS;
3663
3664         Status = BcmFlash2xBulkRead(Adapter,
3665                                             (PUINT)psISOHeader,
3666                                                 IsoImage,
3667                                                 0,
3668                                                 sizeof(ISO_HEADER));
3669
3670         if(Status == STATUS_SUCCESS)
3671         {
3672                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageMagicNumber :0X%x", ntohl(psISOHeader->ISOImageMagicNumber));
3673                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageSize :0X%x ",ntohl(psISOHeader->ISOImageSize));
3674                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageCRC :0X%x",ntohl(psISOHeader->ISOImageCRC));
3675                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImagePriority :0X%x",ntohl(psISOHeader->ISOImagePriority));
3676         }
3677         else
3678         {
3679                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ISO Header Read failed");
3680         }
3681         return Status;
3682 }
3683
3684 /**
3685 *       BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
3686 *       @Adapter : Driver private Data Structure
3687 *
3688 *       Return Value:-
3689 *               Sucsess:- STATUS_SUCESS
3690 *               Failure- : negative erro code
3691 *
3692 **/
3693
3694 INT BcmGetActiveISO(PMINI_ADAPTER Adapter)
3695 {
3696
3697         INT HighestPriISO = 0 ;
3698         HighestPriISO = getHighestPriISO(Adapter);
3699
3700         Adapter->eActiveISO = HighestPriISO ;
3701         if(Adapter->eActiveISO == ISO_IMAGE2)
3702                 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
3703         else if(Adapter->eActiveISO == ISO_IMAGE1)
3704                 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3705
3706         if(Adapter->eActiveISO)
3707                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Active ISO :%x", Adapter->eActiveISO);
3708
3709         return STATUS_SUCCESS;
3710 }
3711
3712 /**
3713 *       IsOffsetWritable :- it will tell the access permission of the sector having passed offset
3714 *       @Adapter : Drivers Private Data Structure
3715 *       @uiOffset : Offset provided in the Flash
3716 *
3717 *       Return Value:-
3718 *       Sucess:-TRUE ,  offset is writable
3719 *       Failure:-FALSE, offset is RO
3720 *
3721 **/
3722 B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset)
3723 {
3724         UINT uiSectorNum = 0;
3725         UINT uiWordOfSectorPermission =0;
3726         UINT uiBitofSectorePermission = 0;
3727         B_UINT32 permissionBits = 0;
3728         uiSectorNum = uiOffset/Adapter->uiSectorSize;
3729
3730         //calculating the word having this Sector Access permission from SectorAccessBitMap Array
3731         uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum /16];
3732
3733         //calculating the bit index inside the word for  this sector
3734         uiBitofSectorePermission = 2*(15 - uiSectorNum %16);
3735
3736         //Setting Access permission
3737         permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission) ;
3738         permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
3739         if(permissionBits == SECTOR_READWRITE_PERMISSION)
3740                 return  TRUE;
3741         else
3742                 return FALSE;
3743 }
3744
3745 static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
3746 {
3747     PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
3748         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
3749         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE1  :0X%x", psFlash2xBitMap->ISO_IMAGE1);
3750         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE2  :0X%x", psFlash2xBitMap->ISO_IMAGE2);
3751         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD0  :0X%x", psFlash2xBitMap->DSD0);
3752         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD1  :0X%x", psFlash2xBitMap->DSD1);
3753         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD2  :0X%x", psFlash2xBitMap->DSD2);
3754         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA0  :0X%x", psFlash2xBitMap->VSA0);
3755         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA1  :0X%x", psFlash2xBitMap->VSA1);
3756         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA2  :0X%x", psFlash2xBitMap->VSA2);
3757         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"SCSI  :0X%x", psFlash2xBitMap->SCSI);
3758         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"CONTROL_SECTION  :0X%x", psFlash2xBitMap->CONTROL_SECTION);
3759
3760         return STATUS_SUCCESS;
3761 }
3762
3763 /**
3764 *       BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
3765 *       8bit has been assigned to every section.
3766         bit[0] :Section present or not
3767         bit[1] :section is valid or not
3768         bit[2] : Secton is read only or has write permission too.
3769         bit[3] : Active Section -
3770         bit[7...4] = Reserved .
3771
3772         @Adapter:-Driver private Data Structure
3773 *
3774 *       Return value:-
3775 *       Sucess:- STATUS_SUCESS
3776 *       Failure:- negative error code
3777 **/
3778
3779 INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap)
3780 {
3781
3782
3783         PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
3784         FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
3785         FLASH2X_SECTION_VAL uiHighestPriISO= 0 ;
3786         BOOLEAN SetActiveDSDDone = FALSE ;
3787         BOOLEAN SetActiveISODone = FALSE ;
3788
3789         //For 1.x map all the section except DSD0 will be shown as not present
3790         //This part will be used by calibration tool to detect the number of DSD present in Flash.
3791         if(IsFlash2x(Adapter) == FALSE)
3792         {
3793                 psFlash2xBitMap->ISO_IMAGE2 = 0;
3794                 psFlash2xBitMap->ISO_IMAGE1 = 0;
3795                 psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF;   //0000(Reseved)1(Active)0(RW)1(valid)1(present)
3796                 psFlash2xBitMap->DSD1  = 0 ;
3797                 psFlash2xBitMap->DSD2 = 0 ;
3798                 psFlash2xBitMap->VSA0 = 0 ;
3799                 psFlash2xBitMap->VSA1 = 0 ;
3800                 psFlash2xBitMap->VSA2 = 0 ;
3801                 psFlash2xBitMap->CONTROL_SECTION = 0 ;
3802                 psFlash2xBitMap->SCSI= 0 ;
3803                 psFlash2xBitMap->Reserved0 = 0 ;
3804                 psFlash2xBitMap->Reserved1 = 0 ;
3805                 psFlash2xBitMap->Reserved2 = 0 ;
3806                 return STATUS_SUCCESS ;
3807
3808         }
3809
3810         uiHighestPriDSD = getHighestPriDSD(Adapter);
3811         uiHighestPriISO = getHighestPriISO(Adapter);
3812
3813         ///
3814         //      IS0 IMAGE 2
3815         ///
3816         if((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS)
3817         {
3818                 //Setting the 0th Bit representing the Section is present or not.
3819                 psFlash2xBitMap->ISO_IMAGE2= psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
3820
3821
3822                 if(ReadISOSignature(Adapter,ISO_IMAGE2)== ISO_IMAGE_MAGIC_NUMBER)
3823                         psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
3824
3825
3826                 //Calculation for extrating the Access permission
3827                 if(IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
3828                         psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
3829
3830                 if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2)
3831                 {
3832                         psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT ;
3833                         SetActiveISODone = TRUE;
3834                 }
3835
3836         }
3837
3838         ///
3839         //      IS0 IMAGE 1
3840         ///
3841         if((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS)
3842         {
3843                 //Setting the 0th Bit representing the Section is present or not.
3844                 psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
3845
3846                 if(ReadISOSignature(Adapter,ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
3847                         psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
3848
3849                 //      Calculation for extrating the Access permission
3850                 if(IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
3851                         psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
3852
3853                 if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1)
3854                 {
3855                         psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT ;
3856                         SetActiveISODone = TRUE;
3857                 }
3858         }
3859
3860
3861
3862         ///
3863         // DSD2
3864         ///
3865         if((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS)
3866         {
3867                 //Setting the 0th Bit representing the Section is present or not.
3868                 psFlash2xBitMap->DSD2= psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
3869
3870                 if(ReadDSDSignature(Adapter,DSD2)== DSD_IMAGE_MAGIC_NUMBER)
3871                         psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
3872
3873                 //Calculation for extrating the Access permission
3874                 if(IsSectionWritable(Adapter, DSD2) == FALSE)
3875                 {
3876                         psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
3877
3878                 }
3879                 else
3880                 {
3881                         //Means section is writable
3882                         if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2))
3883                         {
3884                                 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT ;
3885                                 SetActiveDSDDone =TRUE ;
3886                         }
3887                 }
3888         }
3889
3890         ///
3891         //      DSD 1
3892         ///
3893         if((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS)
3894         {
3895                 //Setting the 0th Bit representing the Section is present or not.
3896                 psFlash2xBitMap->DSD1= psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
3897
3898
3899                 if(ReadDSDSignature(Adapter,DSD1)== DSD_IMAGE_MAGIC_NUMBER)
3900                         psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
3901
3902                 //Calculation for extrating the Access permission
3903                 if(IsSectionWritable(Adapter, DSD1) == FALSE)
3904                 {
3905                         psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
3906                 }
3907                 else
3908                 {
3909                         //Means section is writable
3910                         if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1))
3911                         {
3912                                         psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT ;
3913                                         SetActiveDSDDone =TRUE ;
3914                         }
3915                 }
3916
3917         }
3918
3919         ///
3920         //For DSD 0
3921         //
3922         if((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS)
3923         {
3924                 //Setting the 0th Bit representing the Section is present or not.
3925                 psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
3926
3927                 if(ReadDSDSignature(Adapter,DSD0) == DSD_IMAGE_MAGIC_NUMBER)
3928                         psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
3929
3930                 //Setting Access permission
3931                 if(IsSectionWritable(Adapter, DSD0) == FALSE)
3932                 {
3933                         psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
3934                 }
3935                 else
3936                 {
3937                         //Means section is writable
3938                         if((SetActiveDSDDone == FALSE) &&(uiHighestPriDSD == DSD0))
3939                         {
3940                                         psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT ;
3941                                         SetActiveDSDDone =TRUE ;
3942                         }
3943                 }
3944         }
3945
3946         ///
3947         //      VSA 0
3948         ///
3949         if((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS)
3950         {
3951                 //Setting the 0th Bit representing the Section is present or not.
3952                 psFlash2xBitMap->VSA0= psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
3953
3954                 //Setting the Access Bit. Map is not defined hece setting it always valid
3955                 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
3956
3957                 //Calculation for extrating the Access permission
3958                 if(IsSectionWritable(Adapter, VSA0) == FALSE)
3959                         psFlash2xBitMap->VSA0 |=  FLASH2X_SECTION_RO;
3960
3961                 //By Default section is Active
3962                 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT ;
3963
3964         }
3965
3966
3967         ///
3968         //       VSA 1
3969         ///
3970
3971         if((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS)
3972         {
3973                 //Setting the 0th Bit representing the Section is present or not.
3974                 psFlash2xBitMap->VSA1= psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
3975
3976                 //Setting the Access Bit. Map is not defined hece setting it always valid
3977                 psFlash2xBitMap->VSA1|= FLASH2X_SECTION_VALID;
3978
3979                 //Checking For Access permission
3980                 if(IsSectionWritable(Adapter, VSA1) == FALSE)
3981                         psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
3982
3983                 //By Default section is Active
3984                 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT ;
3985
3986         }
3987
3988
3989         ///
3990         //      VSA 2
3991         ///
3992
3993         if((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS)
3994         {
3995                 //Setting the 0th Bit representing the Section is present or not.
3996                 psFlash2xBitMap->VSA2= psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
3997
3998
3999                 //Setting the Access Bit. Map is not defined hece setting it always valid
4000                 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
4001
4002                 //Checking For Access permission
4003                 if(IsSectionWritable(Adapter, VSA2) == FALSE)
4004                         psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
4005
4006                 //By Default section is Active
4007                 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT ;
4008         }
4009
4010         ///
4011         // SCSI Section
4012         ///
4013         if((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS)
4014         {
4015                 //Setting the 0th Bit representing the Section is present or not.
4016                 psFlash2xBitMap->SCSI= psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
4017
4018
4019                 //Setting the Access Bit. Map is not defined hece setting it always valid
4020                 psFlash2xBitMap->SCSI|= FLASH2X_SECTION_VALID;
4021
4022                 //Checking For Access permission
4023                 if(IsSectionWritable(Adapter, SCSI) == FALSE)
4024                         psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
4025
4026                 //By Default section is Active
4027                 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT ;
4028
4029         }
4030
4031
4032         ///
4033         //      Control Section
4034         ///
4035         if((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS)
4036         {
4037                 //Setting the 0th Bit representing the Section is present or not.
4038                 psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
4039
4040
4041                 //Setting the Access Bit. Map is not defined hece setting it always valid
4042                 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
4043
4044                 //Checking For Access permission
4045                 if(IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
4046                         psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
4047
4048                 //By Default section is Active
4049                 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT ;
4050
4051         }
4052
4053         ///
4054         //      For Reserved Sections
4055         ///
4056         psFlash2xBitMap->Reserved0 = 0;
4057         psFlash2xBitMap->Reserved0 = 0;
4058         psFlash2xBitMap->Reserved0 = 0;
4059
4060         BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
4061
4062         return STATUS_SUCCESS ;
4063
4064 }
4065 /**
4066 BcmSetActiveSection :- Set Active section is used to make priority field highest over other
4067                                         section of same type.
4068
4069 @Adapater :- Bcm Driver Private Data Structure
4070 @eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
4071
4072 Return Value:- Make the priorit highest else return erorr code
4073
4074 **/
4075 INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal)
4076 {
4077         unsigned int SectImagePriority = 0;
4078         INT Status =STATUS_SUCCESS;
4079
4080         //DSD_HEADER sDSD = {0};
4081         //ISO_HEADER sISO = {0};
4082         INT HighestPriDSD = 0 ;
4083         INT HighestPriISO = 0;
4084
4085
4086
4087         Status = IsSectionWritable(Adapter,eFlash2xSectVal) ;
4088         if(Status != TRUE )
4089         {
4090                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section <%d> is not writable",eFlash2xSectVal);
4091                 return STATUS_FAILURE;
4092         }
4093
4094         Adapter->bHeaderChangeAllowed = TRUE ;
4095         switch(eFlash2xSectVal)
4096         {
4097                 case ISO_IMAGE1 :
4098                 case ISO_IMAGE2 :
4099                         if(ReadISOSignature(Adapter,eFlash2xSectVal)== ISO_IMAGE_MAGIC_NUMBER )
4100                         {
4101                                 HighestPriISO = getHighestPriISO(Adapter);
4102
4103                                 if(HighestPriISO == eFlash2xSectVal     )
4104                                 {
4105                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already  has highest priority",eFlash2xSectVal );
4106                                         Status = STATUS_SUCCESS ;
4107                                         break;
4108                                 }
4109
4110                                 SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
4111
4112                                 if((SectImagePriority <= 0) && IsSectionWritable(Adapter,HighestPriISO))
4113                                 {
4114                                         // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
4115                                         // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
4116                                         // by user
4117                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
4118                                         SectImagePriority = htonl(0x1);
4119                                         Status = BcmFlash2xBulkWrite(Adapter,
4120                                                                 &SectImagePriority,
4121                                                                 HighestPriISO,
4122                                                                 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
4123                                                                 SIGNATURE_SIZE,
4124                                                                 TRUE);
4125
4126                                         if(Status)
4127                                         {
4128                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
4129                                                 Status = STATUS_FAILURE;
4130                                                 break ;
4131                                         }
4132
4133                                         HighestPriISO = getHighestPriISO(Adapter);
4134
4135                                         if(HighestPriISO == eFlash2xSectVal     )
4136                                         {
4137                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already  has highest priority",eFlash2xSectVal );
4138                                                 Status = STATUS_SUCCESS ;
4139                                                 break;
4140                                         }
4141
4142                                         SectImagePriority = 2;
4143                                  }
4144
4145
4146                                 SectImagePriority = htonl(SectImagePriority);
4147
4148                                 Status = BcmFlash2xBulkWrite(Adapter,
4149                                                                 &SectImagePriority,
4150                                                                 eFlash2xSectVal,
4151                                                                 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
4152                                                                 SIGNATURE_SIZE,
4153                                                                 TRUE);
4154                                 if(Status)
4155                                 {
4156                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
4157                                         break ;
4158                                 }
4159                         }
4160                         else
4161                         {
4162                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
4163                                 Status = STATUS_FAILURE ;
4164                                 break;
4165                         }
4166                         break;
4167                 case DSD0 :
4168                 case DSD1 :
4169                 case DSD2 :
4170                         if(ReadDSDSignature(Adapter,eFlash2xSectVal)== DSD_IMAGE_MAGIC_NUMBER)
4171                         {
4172                                 HighestPriDSD = getHighestPriDSD(Adapter);
4173
4174                                 if((HighestPriDSD == eFlash2xSectVal))
4175                                 {
4176                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given DSD<%x> already  has highest priority", eFlash2xSectVal);
4177                                         Status = STATUS_SUCCESS ;
4178                                         break;
4179                                 }
4180
4181                                 SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1 ;
4182                                 if(SectImagePriority <= 0)
4183                                 {
4184                                         // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
4185                                         // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
4186                                         // by user
4187                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
4188                                         SectImagePriority = htonl(0x1);
4189
4190                                         Status = BcmFlash2xBulkWrite(Adapter,
4191                                                                         &SectImagePriority,
4192                                                                         HighestPriDSD,
4193                                                                         Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
4194                                                                         SIGNATURE_SIZE,
4195                                                                         TRUE);
4196
4197                                         if(Status)
4198                                         {
4199                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
4200                                                 break ;
4201                                         }
4202
4203                                         HighestPriDSD = getHighestPriDSD(Adapter);
4204
4205                                         if((HighestPriDSD == eFlash2xSectVal))
4206                                         {
4207                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
4208                                                 Status = STATUS_SUCCESS ;
4209                                                 break;
4210                                         }
4211
4212                                         SectImagePriority = htonl(0x2);
4213                                         Status = BcmFlash2xBulkWrite(Adapter,
4214                                                                         &SectImagePriority,
4215                                                                         HighestPriDSD,
4216                                                                         Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
4217                                                                         SIGNATURE_SIZE,
4218                                                                         TRUE);
4219
4220                                         if(Status)
4221                                         {
4222                                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
4223                                                 break ;
4224                                         }
4225
4226                                         HighestPriDSD = getHighestPriDSD(Adapter);
4227
4228                                         if((HighestPriDSD == eFlash2xSectVal))
4229                                         {
4230                                                 Status = STATUS_SUCCESS ;
4231                                                 break;
4232                                         }
4233                                         SectImagePriority = 3 ;
4234
4235                                 }
4236                                 SectImagePriority = htonl(SectImagePriority);
4237                                 Status = BcmFlash2xBulkWrite(Adapter,
4238                                                                 &SectImagePriority,
4239                                                                 eFlash2xSectVal,
4240                                                                 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
4241                                                                 SIGNATURE_SIZE ,
4242                                                                 TRUE);
4243                                 if(Status)
4244                                 {
4245                                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
4246                                         Status = STATUS_FAILURE ;
4247                                         break ;
4248                                 }
4249                         }
4250                         else
4251                         {
4252                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
4253                                 Status = STATUS_FAILURE ;
4254                                 break;
4255                         }
4256                         break;
4257                 case VSA0 :
4258                 case VSA1 :
4259                 case VSA2 :
4260                         //Has to be decided
4261                         break ;
4262                 default :
4263                                 Status = STATUS_FAILURE ;
4264                                 break;
4265
4266         }
4267
4268         Adapter->bHeaderChangeAllowed = FALSE ;
4269         return Status;
4270
4271 }
4272
4273 /**
4274 BcmCopyISO - Used only for copying the ISO section
4275 @Adapater :- Bcm Driver Private Data Structure
4276 @sCopySectStrut :- Section copy structure
4277
4278 Return value:- SUCCESS if copies successfully else negative error code
4279
4280 **/
4281 INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
4282 {
4283
4284         PCHAR Buff = NULL;
4285         FLASH2X_SECTION_VAL eISOReadPart = 0,eISOWritePart = 0;
4286         UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
4287         UINT uiTotalDataToCopy = 0;
4288         BOOLEAN IsThisHeaderSector = FALSE ;
4289         UINT sigOffset = 0;
4290         UINT ISOLength = 0;
4291         UINT Status = STATUS_SUCCESS;
4292         UINT SigBuff[MAX_RW_SIZE];
4293         UINT i = 0;
4294
4295         if(ReadISOSignature(Adapter,sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER)
4296         {
4297                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
4298                 return STATUS_FAILURE;
4299         }
4300
4301         Status = BcmFlash2xBulkRead(Adapter,
4302                                            &ISOLength,
4303                                            sCopySectStrut.SrcSection,
4304                                            0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageSize),
4305                                            4);
4306
4307         if(Status)
4308         {
4309                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
4310                 return Status;
4311         }
4312
4313         ISOLength = htonl(ISOLength);
4314
4315         if(ISOLength % Adapter->uiSectorSize)
4316         {
4317                 ISOLength = Adapter->uiSectorSize*(1 + ISOLength/Adapter->uiSectorSize);
4318         }
4319
4320         sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);
4321
4322         Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
4323
4324         if(Buff == NULL)
4325         {
4326                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for section size");
4327                         return -ENOMEM;
4328         }
4329
4330         if(sCopySectStrut.SrcSection ==ISO_IMAGE1 && sCopySectStrut.DstSection ==ISO_IMAGE2)
4331         {
4332                 eISOReadPart = ISO_IMAGE1 ;
4333                 eISOWritePart = ISO_IMAGE2 ;
4334                 uiReadOffsetWithinPart =  0;
4335                 uiWriteOffsetWithinPart = 0 ;
4336
4337                 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
4338                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
4339                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
4340                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
4341                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
4342                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
4343
4344                 if(uiTotalDataToCopy < ISOLength)
4345                 {
4346                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
4347                         return STATUS_FAILURE;
4348                 }
4349
4350                 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
4351                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
4352                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
4353                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
4354                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
4355                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
4356
4357                 if(uiTotalDataToCopy < ISOLength)
4358                 {
4359                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
4360                         return STATUS_FAILURE;
4361                 }
4362
4363                 uiTotalDataToCopy = ISOLength;
4364
4365                 CorruptISOSig(Adapter,ISO_IMAGE2);
4366
4367                 while(uiTotalDataToCopy)
4368                 {
4369                         if(uiTotalDataToCopy == Adapter->uiSectorSize)
4370                         {
4371                                 //Setting for write of first sector. First sector is assumed to be written in last
4372                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
4373                                 eISOReadPart = ISO_IMAGE1 ;
4374                                 uiReadOffsetWithinPart = 0;
4375                                 eISOWritePart = ISO_IMAGE2;
4376                                 uiWriteOffsetWithinPart = 0 ;
4377                                 IsThisHeaderSector = TRUE ;
4378
4379                         }
4380                         else
4381                         {
4382                                 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
4383                                 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
4384
4385                                 if((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) ))
4386                                 {
4387                                         eISOReadPart = ISO_IMAGE1_PART2 ;
4388                                         uiReadOffsetWithinPart = 0;
4389                                 }
4390                                 if((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
4391                                 {
4392                                         eISOReadPart = ISO_IMAGE1_PART3 ;
4393                                         uiReadOffsetWithinPart = 0;
4394                                 }
4395                                 if((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)))
4396                                 {
4397                                         eISOWritePart = ISO_IMAGE2_PART2 ;
4398                                         uiWriteOffsetWithinPart = 0;
4399                                 }
4400                                 if((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
4401                                 {
4402                                         eISOWritePart = ISO_IMAGE2_PART3 ;
4403                                         uiWriteOffsetWithinPart = 0;
4404                                 }
4405                         }
4406
4407                         Status = BcmFlash2xBulkRead(Adapter,
4408                                                                    (PUINT)Buff,
4409                                                                    eISOReadPart,
4410                                                                    uiReadOffsetWithinPart,
4411                                                                    Adapter->uiSectorSize
4412                                                                 );
4413
4414                         if(Status)
4415                         {
4416                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
4417                                 break;
4418                         }
4419
4420                         if(IsThisHeaderSector == TRUE)
4421                         {
4422                                 //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
4423                                 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
4424
4425                                 for(i = 0; i < MAX_RW_SIZE;i++)
4426                                         *(Buff + sigOffset + i) = 0xFF;
4427                         }
4428                         Adapter->bHeaderChangeAllowed = TRUE ;
4429
4430                         Status = BcmFlash2xBulkWrite(Adapter,
4431                                                                  (PUINT)Buff,
4432                                                                  eISOWritePart,
4433                                                                  uiWriteOffsetWithinPart,
4434                                                                  Adapter->uiSectorSize,
4435                                                                  TRUE);
4436                         if(Status)
4437                         {
4438                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
4439                                 break;
4440                         }
4441
4442                         Adapter->bHeaderChangeAllowed = FALSE;
4443
4444                         if(IsThisHeaderSector == TRUE)
4445                         {
4446                                 WriteToFlashWithoutSectorErase(Adapter,
4447                                                                                                 SigBuff,
4448                                                                                                 eISOWritePart,
4449                                                                                                 sigOffset,
4450                                                                                                 MAX_RW_SIZE);
4451                                 IsThisHeaderSector = FALSE ;
4452                         }
4453                         //substracting the written Data
4454                         uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
4455                 }
4456
4457
4458         }
4459
4460         if(sCopySectStrut.SrcSection ==ISO_IMAGE2 && sCopySectStrut.DstSection ==ISO_IMAGE1)
4461         {
4462                 eISOReadPart = ISO_IMAGE2 ;
4463                 eISOWritePart = ISO_IMAGE1 ;
4464                 uiReadOffsetWithinPart =        0;
4465                 uiWriteOffsetWithinPart = 0 ;
4466
4467                 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
4468                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
4469                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
4470                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
4471                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
4472                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
4473
4474                 if(uiTotalDataToCopy < ISOLength)
4475                 {
4476                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
4477                         return STATUS_FAILURE;
4478                 }
4479
4480                 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
4481                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
4482                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
4483                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
4484                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
4485                                                    (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
4486
4487                 if(uiTotalDataToCopy < ISOLength)
4488                 {
4489                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
4490                         return STATUS_FAILURE;
4491                 }
4492
4493                 uiTotalDataToCopy = ISOLength;
4494
4495                 CorruptISOSig(Adapter,ISO_IMAGE1);
4496
4497                 while(uiTotalDataToCopy)
4498                 {
4499                         if(uiTotalDataToCopy == Adapter->uiSectorSize)
4500                         {
4501                                 //Setting for write of first sector. First sector is assumed to be written in last
4502                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
4503                                 eISOReadPart = ISO_IMAGE2 ;
4504                                 uiReadOffsetWithinPart = 0;
4505                                 eISOWritePart = ISO_IMAGE1;
4506                                 uiWriteOffsetWithinPart = 0 ;
4507                                 IsThisHeaderSector = TRUE;
4508
4509                         }
4510                         else
4511                         {
4512                                 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
4513                                 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
4514
4515                                 if((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) ))
4516                                 {
4517                                         eISOReadPart = ISO_IMAGE2_PART2 ;
4518                                         uiReadOffsetWithinPart = 0;
4519                                 }
4520                                 if((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
4521                                 {
4522                                         eISOReadPart = ISO_IMAGE2_PART3 ;
4523                                         uiReadOffsetWithinPart = 0;
4524                                 }
4525                                 if((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)))
4526                                 {
4527                                         eISOWritePart = ISO_IMAGE1_PART2 ;
4528                                         uiWriteOffsetWithinPart = 0;
4529                                 }
4530                                 if((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
4531                                 {
4532                                         eISOWritePart = ISO_IMAGE1_PART3 ;
4533                                         uiWriteOffsetWithinPart = 0;
4534                                 }
4535                         }
4536
4537                         Status = BcmFlash2xBulkRead(Adapter,
4538                                                                    (PUINT)Buff,
4539                                                                    eISOReadPart,
4540                                                                    uiReadOffsetWithinPart,
4541                                                                    Adapter->uiSectorSize
4542                                                                 );
4543                         if(Status)
4544                         {
4545                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
4546                                 break;
4547                         }
4548
4549                         if(IsThisHeaderSector == TRUE)
4550                         {
4551                                 //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
4552                                 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
4553
4554                                 for(i = 0; i < MAX_RW_SIZE;i++)
4555                                         *(Buff + sigOffset + i) = 0xFF;
4556
4557                         }
4558                         Adapter->bHeaderChangeAllowed = TRUE ;
4559                         Status = BcmFlash2xBulkWrite(Adapter,
4560                                                                  (PUINT)Buff,
4561                                                                  eISOWritePart,
4562                                                                  uiWriteOffsetWithinPart,
4563                                                                  Adapter->uiSectorSize,
4564                                                                  TRUE);
4565
4566                         if(Status)
4567                         {
4568                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
4569                                 break;
4570                         }
4571
4572                         Adapter->bHeaderChangeAllowed = FALSE ;
4573
4574                         if(IsThisHeaderSector == TRUE)
4575                         {
4576                                 WriteToFlashWithoutSectorErase(Adapter,
4577                                                                                                 SigBuff,
4578                                                                                                 eISOWritePart,
4579                                                                                                 sigOffset,
4580                                                                                                 MAX_RW_SIZE);
4581                                 IsThisHeaderSector = FALSE ;
4582                         }
4583
4584                         //substracting the written Data
4585                         uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
4586                 }
4587
4588
4589         }
4590
4591         bcm_kfree(Buff);
4592
4593         return Status;
4594 }
4595 /**
4596 BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
4597                                              It will corrupt the sig, if Section is writable, by making first bytes as zero.
4598 @Adapater :- Bcm Driver Private Data Structure
4599 @eFlash2xSectionVal :- Flash section val which has header
4600
4601 Return Value :-
4602         Sucess :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
4603         Failure :-Return negative error code
4604
4605
4606 **/
4607 INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
4608 {
4609
4610         INT Status = STATUS_SUCCESS ;
4611         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Section Value :%x \n", eFlash2xSectionVal);
4612
4613         if((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2))
4614         {
4615                 Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
4616         }
4617         else if(eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2)
4618         {
4619                 Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
4620         }
4621         else
4622         {
4623                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given Section <%d>does not have Header",eFlash2xSectionVal);
4624                 return STATUS_SUCCESS;
4625         }
4626         return Status;
4627 }
4628 /**
4629 BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
4630                                           header and  Write Permission.
4631 @Adapater :- Bcm Driver Private Data Structure
4632 @eFlashSectionVal :- Flash section val which has header
4633
4634 Return Value :-
4635         Sucess :- If Section is present and writable write the sig and return STATUS_SUCCESS
4636         Failure :-Return negative error code
4637
4638 **/
4639 INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
4640 {
4641
4642         UINT uiSignature = 0 ;
4643         UINT uiOffset = 0;
4644         //DSD_HEADER dsdHeader = {0};
4645
4646         if(Adapter->bSigCorrupted == FALSE)
4647         {
4648                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Signature is not corrupted by driver, hence not restoring\n");
4649                 return STATUS_SUCCESS;
4650         }
4651         if(Adapter->bAllDSDWriteAllow == FALSE)
4652         {
4653                 if(IsSectionWritable(Adapter,eFlashSectionVal) == FALSE)
4654                 {
4655                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Write signature");
4656                         return SECTOR_IS_NOT_WRITABLE;
4657                 }
4658         }
4659         if((eFlashSectionVal == DSD0) ||(eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2))
4660         {
4661                 uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER) ;
4662                 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader ;
4663
4664                 uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber);
4665
4666                 if((ReadDSDSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
4667                 {
4668                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corrupted Pattern is not there. Hence won't write sig");
4669                         return STATUS_FAILURE;
4670                 }
4671
4672         }
4673         else if((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2))
4674         {
4675                 uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
4676                 //uiOffset = 0;
4677                 uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber);
4678                 if((ReadISOSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
4679                 {
4680                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Currupted Pattern is not there. Hence won't write sig");
4681                         return STATUS_FAILURE;
4682                 }
4683         }
4684         else
4685         {
4686                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
4687                 return STATUS_FAILURE;
4688         }
4689
4690         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature");
4691
4692
4693         Adapter->bHeaderChangeAllowed = TRUE;
4694         Adapter->bSigCorrupted = FALSE;
4695         BcmFlash2xBulkWrite(Adapter, &uiSignature,eFlashSectionVal,uiOffset,SIGNATURE_SIZE,TRUE);
4696         Adapter->bHeaderChangeAllowed = FALSE;
4697
4698
4699
4700         return STATUS_SUCCESS;
4701 }
4702 /**
4703 validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
4704                                                       if requested Bytes goes beyond the Requested section, it reports error.
4705 @Adapater :- Bcm Driver Private Data Structure
4706 @psFlash2xReadWrite :-Flash2x Read/write structure pointer
4707
4708 Return values:-Return TRUE is request is valid else FALSE.
4709
4710
4711 **/
4712 INT     validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite)
4713 {
4714         UINT uiNumOfBytes = 0 ;
4715         UINT uiSectStartOffset = 0 ;
4716         UINT uiSectEndOffset = 0;
4717         uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
4718
4719         if(IsSectionExistInFlash(Adapter,psFlash2xReadWrite->Section) != TRUE)
4720         {
4721                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%x> does not exixt in Flash",psFlash2xReadWrite->Section);
4722                 return FALSE;
4723         }
4724         uiSectStartOffset = BcmGetSectionValStartOffset(Adapter,psFlash2xReadWrite->Section);
4725         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n",uiSectStartOffset,psFlash2xReadWrite->Section);
4726         if((psFlash2xReadWrite->Section == ISO_IMAGE1) ||(psFlash2xReadWrite->Section == ISO_IMAGE2))
4727         {
4728                 if(psFlash2xReadWrite->Section == ISO_IMAGE1)
4729                 {
4730                         uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1) -
4731                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1)+
4732                                                           BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART2) -
4733                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART2)+
4734                                                           BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART3) -
4735                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART3);
4736                 }
4737                 else if(psFlash2xReadWrite->Section == ISO_IMAGE2)
4738                 {
4739                         uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2) -
4740                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)+
4741                                                           BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART2) -
4742                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART2)+
4743                                                           BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART3) -
4744                                                           BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART3);
4745
4746                 }
4747
4748                 //since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset
4749                 //it should be added in startoffset. so that check done in last of this function can be valued.
4750                 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset ;
4751
4752                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Total size of the ISO Image :%x",uiSectEndOffset);
4753         }
4754         else
4755                 uiSectEndOffset   = BcmGetSectionValEndOffset(Adapter,psFlash2xReadWrite->Section);
4756         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x \n",uiSectEndOffset);
4757
4758         //Checking the boundary condition
4759         if((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
4760                 return TRUE;
4761         else
4762         {
4763                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid Request....");
4764                 return FALSE;
4765         }
4766
4767 }
4768
4769 /**
4770 IsFlash2x :- check for Flash 2.x
4771 @Adapater :- Bcm Driver Private Data Structure
4772
4773 Return value:-
4774         return TRUE if flah2.x of hgher version else return false.
4775 **/
4776
4777 INT IsFlash2x(PMINI_ADAPTER Adapter)
4778 {
4779         if(Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
4780                 return TRUE ;
4781         else
4782                 return FALSE;
4783 }
4784 /**
4785 GetFlashBaseAddr :- Calculate the Flash Base address
4786 @Adapater :- Bcm Driver Private Data Structure
4787
4788 Return Value:-
4789         Success :- Base Address of the Flash
4790 **/
4791
4792 INT GetFlashBaseAddr(PMINI_ADAPTER Adapter)
4793 {
4794
4795         UINT uiBaseAddr = 0;
4796
4797         if(Adapter->bDDRInitDone)
4798         {
4799                 /*
4800                 For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
4801                 In case of Raw Read... use the default value
4802                 */
4803                 if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
4804                         !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
4805                         )
4806                         uiBaseAddr = Adapter->uiFlashBaseAdd ;
4807                 else
4808                         uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
4809         }
4810         else
4811         {
4812                 /*
4813                 For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
4814                 In case of Raw Read... use the default value
4815                 */
4816                 if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
4817                         !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
4818                         )
4819                         uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4820                 else
4821                         uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4822         }
4823
4824         return uiBaseAddr ;
4825 }
4826 /**
4827 BcmCopySection :- This API is used to copy the One section in another. Both section should
4828                                     be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
4829
4830 @Adapater :- Bcm Driver Private Data Structure
4831 @SrcSection :- Source section From where data has to be copied
4832 @DstSection :- Destination section to which data has to be copied
4833 @offset :- Offset from/to  where data has to be copied from one section to another.
4834 @numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
4835                              in case of numofBytes  equal zero complete section will be copied.
4836
4837 Return Values-
4838         Sucess : Return STATUS_SUCCESS
4839         Faillure :- return negative error code
4840
4841 **/
4842
4843 INT     BcmCopySection(PMINI_ADAPTER Adapter,
4844                                                 FLASH2X_SECTION_VAL SrcSection,
4845                                                 FLASH2X_SECTION_VAL DstSection,
4846                                                 UINT offset,
4847                                                 UINT numOfBytes)
4848 {
4849         UINT BuffSize = 0 ;
4850         UINT BytesToBeCopied = 0;
4851         PUCHAR pBuff = NULL ;
4852         INT Status = STATUS_SUCCESS ;
4853         if(SrcSection == DstSection)
4854         {
4855                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source and Destination should be different ...try again");
4856                 return -EINVAL;
4857         }
4858         if((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2))
4859         {
4860                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source should be DSD subsection");
4861                 return  -EINVAL;
4862         }
4863         if((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2))
4864         {
4865                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destination should be DSD subsection");
4866                 return  -EINVAL;
4867         }
4868
4869         #if 0
4870         else
4871         {
4872                 if((SrcSection == VSA0) || (SrcSection == VSA1) || (SrcSection == VSA2))
4873                 {
4874                         if((DstSection != VSA0) && (DstSection != VSA1) && (DstSection != VSA2))
4875                         {
4876                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Source and Destion secton is not of same type");
4877                                 return -EINVAL;
4878                         }
4879                 }
4880
4881         }
4882         #endif
4883         //if offset zero means have to copy complete secton
4884
4885         if(numOfBytes == 0)
4886         {
4887                 numOfBytes = BcmGetSectionValEndOffset(Adapter,SrcSection)
4888                                   - BcmGetSectionValStartOffset(Adapter,SrcSection);
4889
4890                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Section Size :0x%x",numOfBytes);
4891         }
4892
4893         if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,SrcSection)
4894                                   - BcmGetSectionValStartOffset(Adapter,SrcSection))
4895         {
4896                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
4897                                                 offset, numOfBytes);
4898                 return -EINVAL;
4899         }
4900
4901         if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,DstSection)
4902                                   - BcmGetSectionValStartOffset(Adapter,DstSection))
4903         {
4904                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
4905                                                 offset, numOfBytes);
4906                 return -EINVAL;
4907         }
4908
4909
4910         if(numOfBytes > Adapter->uiSectorSize )
4911                 BuffSize = Adapter->uiSectorSize;
4912         else
4913                 BuffSize = numOfBytes ;
4914
4915         pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL);
4916         if(pBuff == NULL)
4917         {
4918                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed.. ");
4919                 return -ENOMEM;
4920         }
4921
4922
4923         BytesToBeCopied = Adapter->uiSectorSize ;
4924         if(offset % Adapter->uiSectorSize)
4925                 BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
4926         if(BytesToBeCopied > numOfBytes)
4927                 BytesToBeCopied = numOfBytes ;
4928
4929
4930
4931         Adapter->bHeaderChangeAllowed = TRUE;
4932
4933         do
4934         {
4935                 Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset,BytesToBeCopied);
4936                 if(Status)
4937                 {
4938                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection,BytesToBeCopied);
4939                         break;
4940                 }
4941                 Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pBuff,DstSection,offset,BytesToBeCopied,FALSE);
4942                 if(Status)
4943                 {
4944                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection,BytesToBeCopied);
4945                         break;
4946                 }
4947                 offset = offset + BytesToBeCopied;
4948                 numOfBytes = numOfBytes - BytesToBeCopied ;
4949                 if(numOfBytes)
4950                 {
4951                         if(numOfBytes > Adapter->uiSectorSize )
4952                                 BytesToBeCopied = Adapter->uiSectorSize;
4953                         else
4954                                 BytesToBeCopied = numOfBytes;
4955                 }
4956         }while(numOfBytes > 0) ;
4957         bcm_kfree(pBuff);
4958         Adapter->bHeaderChangeAllowed = FALSE ;
4959         return Status;
4960 }
4961
4962 /**
4963 SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
4964 @Adapater :- Bcm Driver Private Data Structure
4965 @pBuff :- Data buffer that has to be written in sector having the header map.
4966 @uiOffset :- Flash offset that has to be written.
4967
4968 Return value :-
4969         Sucess :- On sucess return STATUS_SUCCESS
4970         Faillure :- Return negative error code
4971
4972 **/
4973
4974 INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset)
4975 {
4976         UINT offsetToProtect = 0,HeaderSizeToProtect =0;
4977         BOOLEAN bHasHeader = FALSE ;
4978         PUCHAR pTempBuff =NULL;
4979         UINT uiSectAlignAddr = 0;
4980         UINT sig = 0;
4981
4982         #if 0
4983         //if Chenges in Header is allowed, Return back
4984         if(Adapter->bHeaderChangeAllowed == TRUE)
4985         {
4986                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Header Change is allowed");
4987                 return STATUS_SUCCESS ;
4988         }
4989         #endif
4990         //making the offset sector alligned
4991         uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4992
4993
4994         if((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD2)- Adapter->uiSectorSize)||
4995         (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD1)- Adapter->uiSectorSize)||
4996         (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD0)- Adapter->uiSectorSize))
4997         {
4998
4999                 //offset from the sector boundry having the header map
5000                 offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
5001                 HeaderSizeToProtect = sizeof(DSD_HEADER);
5002                 bHasHeader = TRUE ;
5003         }
5004
5005         if(uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1) ||
5006                 uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2))
5007         {
5008                 offsetToProtect = 0;
5009                 HeaderSizeToProtect = sizeof(ISO_HEADER);
5010                 bHasHeader = TRUE;
5011         }
5012         //If Header is present overwrite passed buffer with this
5013         if(bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE))
5014         {
5015                 pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL);
5016                 if(pTempBuff == NULL)
5017                 {
5018                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed ");
5019                         return -ENOMEM;
5020                 }
5021                 //Read header
5022                 BeceemFlashBulkRead(Adapter,(PUINT)pTempBuff,(uiSectAlignAddr + offsetToProtect),HeaderSizeToProtect);
5023                 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pTempBuff ,HeaderSizeToProtect);
5024                 //Replace Buffer content with Header
5025                 memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect);
5026
5027                 bcm_kfree(pTempBuff);
5028         }
5029         if(bHasHeader && Adapter->bSigCorrupted)
5030         {
5031                 sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)));
5032                 sig = ntohl(sig);
5033                 if((sig & 0xFF000000) != CORRUPTED_PATTERN)
5034                 {
5035                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Desired pattern is not at sig offset. Hence won't restore");
5036                         Adapter->bSigCorrupted = FALSE;
5037                         return STATUS_SUCCESS;
5038                 }
5039                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Corrupted sig is :%X", sig);
5040                 *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)))= htonl(DSD_IMAGE_MAGIC_NUMBER);
5041                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature in Header Write only");
5042                 Adapter->bSigCorrupted = FALSE;
5043         }
5044
5045         return STATUS_SUCCESS ;
5046 }
5047 INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset)
5048 {
5049         UINT GPIOConfig = 0 ;
5050
5051
5052         if(Adapter->bFlashRawRead == FALSE)
5053         {
5054                 //Applicable for Flash2.x
5055                 if(IsFlash2x(Adapter) == FALSE)
5056                         return STATUS_SUCCESS;
5057         }
5058
5059         if(offset/FLASH_PART_SIZE)
5060         {
5061                 //bit[14..12] -> will select make Active CS1, CS2 or CS3
5062                 // Select CS1, CS2 and CS3 (CS0 is dedicated pin)
5063                 rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
5064                 GPIOConfig |= (7 << 12);
5065                 wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
5066         }
5067
5068         return STATUS_SUCCESS ;
5069 }
5070 /**
5071 BcmDoChipSelect : This will selcet the appropriate chip for writing.
5072 @Adapater :- Bcm Driver Private Data Structure
5073
5074 OutPut:-
5075         Select the Appropriate chip and retrn status Sucess
5076 **/
5077 INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset)
5078 {
5079         UINT FlashConfig = 0;
5080         INT ChipNum = 0;
5081         UINT GPIOConfig = 0;
5082         UINT PartNum = 0;
5083
5084         ChipNum = offset / FLASH_PART_SIZE ;
5085
5086         //
5087         // Chip Select mapping to enable flash0.
5088         // To select flash 0, we have to OR with (0<<12).
5089         // ORing 0 will have no impact so not doing that part.
5090         // In future if Chip select value changes from 0 to non zero,
5091         // That needs be taken care with backward comaptibility. No worries for now.
5092         //
5093
5094         /*
5095         SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
5096         if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
5097         Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
5098         power down modes (Idle mode/shutdown mode), the values in the register will be different.
5099         */
5100
5101         if(Adapter->SelectedChip == ChipNum)
5102                 return STATUS_SUCCESS;
5103
5104         //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum);
5105         Adapter->SelectedChip = ChipNum ;
5106
5107         //bit[13..12]  will select the appropriate chip
5108         rdmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
5109         rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
5110
5111         {
5112                 switch(ChipNum)
5113                 {
5114                 case 0:
5115                         PartNum = 0;
5116                         break;
5117                 case 1:
5118                         PartNum = 3;
5119                         GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
5120                         break;
5121                 case 2:
5122                         PartNum = 1;
5123                         GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
5124                         break;
5125                 case 3:
5126                         PartNum = 2;
5127                         GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
5128                         break;
5129                 }
5130         }
5131         /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
5132             nothing to do... can return immediately.
5133             ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
5134             Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
5135             These values are not written by host other than during CHIP_SELECT.
5136         */
5137         if(PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
5138                 return STATUS_SUCCESS;
5139
5140         //clearing the bit[13..12]
5141         FlashConfig &= 0xFFFFCFFF;
5142         FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); //00
5143
5144         wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
5145         udelay(100);
5146
5147         wrmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
5148         udelay(100);
5149
5150         return STATUS_SUCCESS;
5151
5152 }
5153 INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
5154 {
5155                 UINT uiDSDsig = 0;
5156                 //UINT sigoffsetInMap = 0;
5157                 //DSD_HEADER dsdHeader = {0};
5158
5159
5160                 //sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader;
5161
5162                 if(dsd != DSD0 && dsd != DSD1 && dsd != DSD2)
5163                 {
5164                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for DSDs");
5165                         return STATUS_FAILURE;
5166                 }
5167                 BcmFlash2xBulkRead(Adapter,
5168                                                    &uiDSDsig,
5169                                                    dsd,
5170                                                    Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber),
5171                                                    SIGNATURE_SIZE);
5172
5173                 uiDSDsig = ntohl(uiDSDsig);
5174                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD SIG :%x", uiDSDsig);
5175
5176                 return uiDSDsig ;
5177 }
5178 INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
5179 {
5180         //UINT priOffsetInMap = 0 ;
5181         unsigned int uiDSDPri = STATUS_FAILURE;
5182         //DSD_HEADER dsdHeader = {0};
5183         //priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
5184         if(IsSectionWritable(Adapter,dsd))
5185         {
5186                 if(ReadDSDSignature(Adapter,dsd)== DSD_IMAGE_MAGIC_NUMBER)
5187                 {
5188                         BcmFlash2xBulkRead(Adapter,
5189                                                            &uiDSDPri,
5190                                                            dsd,
5191                                                            Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader +FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
5192                                                            4);
5193
5194                         uiDSDPri = ntohl(uiDSDPri);
5195                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD<%x> Priority :%x", dsd, uiDSDPri);
5196
5197                 }
5198         }
5199         return uiDSDPri;
5200 }
5201 FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter)
5202 {
5203         INT DSDHighestPri = STATUS_FAILURE;
5204         INT  DsdPri= 0 ;
5205         FLASH2X_SECTION_VAL HighestPriDSD = 0 ;
5206
5207         if(IsSectionWritable(Adapter,DSD2))
5208         {
5209                 DSDHighestPri = ReadDSDPriority(Adapter,DSD2);
5210                 HighestPriDSD = DSD2 ;
5211         }
5212         if(IsSectionWritable(Adapter,DSD1))
5213         {
5214                  DsdPri = ReadDSDPriority(Adapter,DSD1);
5215                  if(DSDHighestPri  < DsdPri)
5216                  {
5217                         DSDHighestPri = DsdPri ;
5218                         HighestPriDSD = DSD1;
5219                  }
5220         }
5221         if(IsSectionWritable(Adapter,DSD0))
5222         {
5223                  DsdPri = ReadDSDPriority(Adapter,DSD0);
5224                  if(DSDHighestPri  < DsdPri)
5225                  {
5226                         DSDHighestPri = DsdPri ;
5227                         HighestPriDSD = DSD0;
5228                  }
5229         }
5230         if(HighestPriDSD)
5231                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest DSD :%x , and its  Pri :%x", HighestPriDSD, DSDHighestPri);
5232         return  HighestPriDSD ;
5233 }
5234
5235 INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
5236 {
5237                 UINT uiISOsig = 0;
5238                 //UINT sigoffsetInMap = 0;
5239                 //ISO_HEADER ISOHeader = {0};
5240
5241
5242                 //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
5243
5244                 if(iso != ISO_IMAGE1 && iso != ISO_IMAGE2)
5245                 {
5246                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for ISOs");
5247                         return STATUS_FAILURE;
5248                 }
5249                 BcmFlash2xBulkRead(Adapter,
5250                                                    &uiISOsig,
5251                                                    iso,
5252                                                    0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber),
5253                                                    SIGNATURE_SIZE);
5254
5255                 uiISOsig = ntohl(uiISOsig);
5256                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO SIG :%x", uiISOsig);
5257
5258                 return uiISOsig ;
5259 }
5260 INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
5261 {
5262
5263         unsigned int ISOPri = STATUS_FAILURE;
5264         if(IsSectionWritable(Adapter,iso))
5265         {
5266                 if(ReadISOSignature(Adapter,iso)== ISO_IMAGE_MAGIC_NUMBER)
5267                 {
5268                         BcmFlash2xBulkRead(Adapter,
5269                                                            &ISOPri,
5270                                                            iso,
5271                                                            0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
5272                                                            4);
5273
5274                         ISOPri = ntohl(ISOPri);
5275                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO<%x> Priority :%x", iso, ISOPri);
5276
5277                 }
5278         }
5279         return ISOPri;
5280 }
5281 FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter)
5282 {
5283         INT ISOHighestPri = STATUS_FAILURE;
5284         INT  ISOPri= 0 ;
5285         FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL ;
5286
5287         if(IsSectionWritable(Adapter,ISO_IMAGE2))
5288         {
5289                 ISOHighestPri = ReadISOPriority(Adapter,ISO_IMAGE2);
5290                 HighestPriISO = ISO_IMAGE2 ;
5291         }
5292         if(IsSectionWritable(Adapter,ISO_IMAGE1))
5293         {
5294                  ISOPri = ReadISOPriority(Adapter,ISO_IMAGE1);
5295                  if(ISOHighestPri  < ISOPri)
5296                  {
5297                         ISOHighestPri = ISOPri ;
5298                         HighestPriISO = ISO_IMAGE1;
5299                  }
5300         }
5301         if(HighestPriISO)
5302                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest ISO :%x and its Pri :%x",HighestPriISO,ISOHighestPri);
5303         return  HighestPriISO ;
5304 }
5305 INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
5306                                                                                 PUINT pBuff,
5307                                                                                 FLASH2X_SECTION_VAL eFlash2xSectionVal,
5308                                                                                 UINT uiOffset,
5309                                                                                 UINT uiNumBytes
5310                                                                                 )
5311 {
5312 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
5313         UINT uiTemp = 0, value = 0 ;
5314         UINT i = 0;
5315         UINT uiPartOffset = 0;
5316 #endif
5317         UINT uiStartOffset = 0;
5318         //Adding section start address
5319         INT Status = STATUS_SUCCESS;
5320         PUCHAR pcBuff = (PUCHAR)pBuff;
5321
5322         if(uiNumBytes % Adapter->ulFlashWriteSize)
5323         {
5324                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
5325                 return STATUS_FAILURE;
5326         }
5327
5328         uiStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
5329
5330         if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
5331         {
5332                 return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
5333         }
5334
5335         uiOffset = uiOffset + uiStartOffset;
5336
5337 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
5338   Status = bcmflash_raw_writenoerase((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE), pcBuff,uiNumBytes);
5339 #else
5340         rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
5341         value = 0;
5342         wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
5343
5344         Adapter->SelectedChip = RESET_CHIP_SELECT;
5345         BcmDoChipSelect(Adapter,uiOffset);
5346         uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
5347
5348         for(i = 0 ; i< uiNumBytes; i += Adapter->ulFlashWriteSize)
5349         {
5350                 if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
5351                         Status = flashByteWrite(Adapter,uiPartOffset, pcBuff);
5352                 else
5353                         Status = flashWrite(Adapter,uiPartOffset, pcBuff);
5354
5355                 if(Status != STATUS_SUCCESS)
5356                         break;
5357
5358                 pcBuff = pcBuff + Adapter->ulFlashWriteSize;
5359                 uiPartOffset = uiPartOffset +  Adapter->ulFlashWriteSize;
5360         }
5361         wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
5362         Adapter->SelectedChip = RESET_CHIP_SELECT;
5363 #endif
5364
5365         return Status;
5366 }
5367
5368 #if 0
5369 UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType)
5370 {
5371
5372         UINT numOfWRSubSec = 0;
5373         switch(secType)
5374         {
5375                 case ISO :
5376                         if(IsSectionWritable(Adapter,ISO_IMAGE1))
5377                                 numOfWRSubSec = numOfWRSubSec + 1;
5378                         if(IsSectionWritable(Adapter,ISO_IMAGE2))
5379                                 numOfWRSubSec = numOfWRSubSec + 1;
5380                         break;
5381
5382                 case DSD :
5383                         if(IsSectionWritable(Adapter,DSD2))
5384                                 numOfWRSubSec = numOfWRSubSec + 1;
5385                         if(IsSectionWritable(Adapter,DSD1))
5386                                 numOfWRSubSec = numOfWRSubSec + 1;
5387                         if(IsSectionWritable(Adapter,DSD0))
5388                                 numOfWRSubSec = numOfWRSubSec + 1;
5389                         break ;
5390
5391                 case VSA :
5392                                 //for VSA Add code Here
5393                  default :
5394                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Invalid secton<%d> is passed", secType);\
5395                         numOfWRSubSec = 0;
5396
5397         }
5398         return numOfWRSubSec;
5399 }
5400 #endif
5401 BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
5402 {
5403
5404         BOOLEAN SectionPresent = FALSE ;
5405
5406         switch(section)
5407         {
5408
5409                 case ISO_IMAGE1 :
5410                           if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
5411                                         (IsNonCDLessDevice(Adapter) == FALSE))
5412                                   SectionPresent = TRUE ;
5413                            break;
5414                 case ISO_IMAGE2 :
5415                                 if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
5416                                         (IsNonCDLessDevice(Adapter) == FALSE))
5417                                          SectionPresent = TRUE ;
5418                           break;
5419                 case DSD0 :
5420                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
5421                                          SectionPresent = TRUE ;
5422                                 break;
5423                 case DSD1 :
5424                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
5425                                          SectionPresent = TRUE ;
5426                                 break;
5427                 case DSD2 :
5428                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
5429                                          SectionPresent = TRUE ;
5430                                 break;
5431                 case VSA0 :
5432                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
5433                                          SectionPresent = TRUE ;
5434                                 break;
5435                 case VSA1 :
5436                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
5437                                          SectionPresent = TRUE ;
5438                                 break;
5439                 case VSA2 :
5440                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
5441                                          SectionPresent = TRUE ;
5442                                 break;
5443                 case SCSI :
5444                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
5445                                          SectionPresent = TRUE ;
5446                                 break;
5447                 case CONTROL_SECTION :
5448                                 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
5449                                          SectionPresent = TRUE ;
5450                                 break;
5451                 default :
5452                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
5453                         SectionPresent =  FALSE;
5454         }
5455         return SectionPresent ;
5456 }
5457 INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section)
5458 {
5459                 INT offset = STATUS_FAILURE;
5460                 INT Status = FALSE;
5461                 if(IsSectionExistInFlash(Adapter,Section) == FALSE)
5462                 {
5463                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section <%d> does not exixt", Section);
5464                         return FALSE;
5465                 }
5466                 offset = BcmGetSectionValStartOffset(Adapter,Section);
5467                 if(offset == INVALID_OFFSET)
5468                 {
5469                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%d> does not exixt", Section);
5470                         return FALSE;
5471                 }
5472
5473                 if(IsSectionExistInVendorInfo(Adapter,Section))
5474                 {
5475                         return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
5476                 }
5477
5478                 Status = IsOffsetWritable(Adapter,offset);
5479                 return Status ;
5480 }
5481
5482 INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
5483 {
5484
5485         PUCHAR pBuff = NULL;
5486         UINT sig = 0;
5487         UINT uiOffset = 0;
5488         UINT BlockStatus = 0;
5489         UINT uiSectAlignAddr = 0;
5490
5491         Adapter->bSigCorrupted = FALSE;
5492
5493         if(Adapter->bAllDSDWriteAllow == FALSE)
5494         {
5495                 if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
5496                 {
5497                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
5498                         return SECTOR_IS_NOT_WRITABLE;
5499                 }
5500         }
5501
5502         pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
5503         if(pBuff == NULL)
5504         {
5505                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
5506                 return -ENOMEM ;
5507         }
5508
5509         uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER);
5510         uiOffset -= MAX_RW_SIZE ;
5511
5512         BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset,MAX_RW_SIZE);
5513
5514
5515         sig = *((PUINT)(pBuff +12));
5516         sig =ntohl(sig);
5517         BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
5518         //Now corrupting the sig by corrupting 4th last Byte.
5519         *(pBuff + 12) = 0;
5520
5521         if(sig == DSD_IMAGE_MAGIC_NUMBER)
5522         {
5523                 Adapter->bSigCorrupted = TRUE;
5524                 if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
5525                 {
5526                         uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize -1);
5527                         BlockStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);
5528
5529                         WriteToFlashWithoutSectorErase(Adapter,(PUINT)(pBuff + 12),eFlash2xSectionVal,
5530                                                                                                 (uiOffset + 12),BYTE_WRITE_SUPPORT);
5531                         if(BlockStatus)
5532                         {
5533                                 BcmRestoreBlockProtectStatus(Adapter,BlockStatus);
5534                                 BlockStatus = 0;
5535                         }
5536                 }
5537                 else
5538                 {
5539                         WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
5540                                                                                                 uiOffset ,MAX_RW_SIZE);
5541                 }
5542         }
5543         else
5544         {
5545                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
5546                 bcm_kfree(pBuff);
5547                 return STATUS_FAILURE;
5548         }
5549
5550         bcm_kfree(pBuff);
5551         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
5552         return STATUS_SUCCESS ;
5553 }
5554
5555 INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
5556 {
5557
5558         PUCHAR pBuff = NULL;
5559         UINT sig = 0;
5560         UINT uiOffset = 0;
5561
5562         Adapter->bSigCorrupted = FALSE;
5563
5564         if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
5565         {
5566                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
5567                 return SECTOR_IS_NOT_WRITABLE;
5568         }
5569
5570         pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
5571         if(pBuff == NULL)
5572         {
5573                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allocate memorey");
5574                 return -ENOMEM ;
5575         }
5576
5577         uiOffset = 0;
5578
5579         BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset, MAX_RW_SIZE);
5580
5581         sig = *((PUINT)pBuff);
5582         sig =ntohl(sig);
5583
5584         //corrupt signature
5585         *pBuff = 0;
5586
5587         if(sig == ISO_IMAGE_MAGIC_NUMBER)
5588         {
5589                 Adapter->bSigCorrupted = TRUE;
5590                 WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
5591                                                                                         uiOffset ,Adapter->ulFlashWriteSize);
5592         }
5593         else
5594         {
5595                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
5596                 bcm_kfree(pBuff);
5597                 return STATUS_FAILURE;
5598         }
5599
5600         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
5601         BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
5602
5603         bcm_kfree(pBuff);
5604         return STATUS_SUCCESS ;
5605 }
5606
5607 BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter)
5608 {
5609         if(Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
5610                 return TRUE;
5611         else
5612                 return FALSE ;
5613 }
5614