Linux 3.3-rc6
[linux/fpc-iii.git] / drivers / staging / bcm / nvm.c
blob7d703cb3c5e0e2e81e3ee1ba84fe41cb78e09f84
1 #include "headers.h"
3 #define DWORD unsigned int
5 static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset);
6 static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter);
7 static INT BcmGetActiveISO(PMINI_ADAPTER Adapter);
8 static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
9 static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
10 static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize);
12 static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
13 static INT BcmGetNvmSize(PMINI_ADAPTER Adapter);
14 static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
15 static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);
17 static INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
19 static B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset);
20 static INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section);
21 static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);
23 static INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
24 static INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
25 static INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
26 static INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
28 static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
29 static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
30 static INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
31 static INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, PUINT pBuff,
32 FLASH2X_SECTION_VAL eFlash2xSectionVal,
33 UINT uiOffset, UINT uiNumBytes);
34 static FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter);
35 static FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter);
37 static INT BeceemFlashBulkRead(
38 PMINI_ADAPTER Adapter,
39 PUINT pBuffer,
40 UINT uiOffset,
41 UINT uiNumBytes);
43 static INT BeceemFlashBulkWrite(
44 PMINI_ADAPTER Adapter,
45 PUINT pBuffer,
46 UINT uiOffset,
47 UINT uiNumBytes,
48 BOOLEAN bVerify);
50 static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter);
52 static INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData);
54 // Procedure: ReadEEPROMStatusRegister
56 // Description: Reads the standard EEPROM Status Register.
58 // Arguments:
59 // Adapter - ptr to Adapter object instance
60 // Returns:
61 // OSAL_STATUS_CODE
63 //-----------------------------------------------------------------------------
65 static UCHAR ReadEEPROMStatusRegister( PMINI_ADAPTER Adapter )
67 UCHAR uiData = 0;
68 DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
69 UINT uiStatus = 0;
70 UINT value = 0;
71 UINT value1 = 0;
73 /* Read the EEPROM status register */
74 value = EEPROM_READ_STATUS_REGISTER ;
75 wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
77 while ( dwRetries != 0 )
79 value=0;
80 uiStatus = 0 ;
81 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
82 if(Adapter->device_removed == TRUE)
84 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got removed hence exiting....");
85 break;
88 /* Wait for Avail bit to be set. */
89 if ( ( uiStatus & EEPROM_READ_DATA_AVAIL) != 0 )
91 /* Clear the Avail/Full bits - which ever is set. */
92 value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
93 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
95 value =0;
96 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
97 uiData = (UCHAR)value;
99 break;
102 dwRetries-- ;
103 if ( dwRetries == 0 )
105 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
106 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
107 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);
108 return uiData;
110 if( !(dwRetries%RETRIES_PER_DELAY) )
111 msleep(1);
112 uiStatus = 0 ;
114 return uiData;
115 } /* ReadEEPROMStatusRegister */
117 //-----------------------------------------------------------------------------
118 // Procedure: ReadBeceemEEPROMBulk
120 // Description: This routine reads 16Byte data from EEPROM
122 // Arguments:
123 // Adapter - ptr to Adapter object instance
124 // dwAddress - EEPROM Offset to read the data from.
125 // pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY.
127 // Returns:
128 // OSAL_STATUS_CODE:
129 //-----------------------------------------------------------------------------
131 INT ReadBeceemEEPROMBulk( PMINI_ADAPTER Adapter,
132 DWORD dwAddress,
133 DWORD *pdwData,
134 DWORD dwNumWords
137 DWORD dwIndex = 0;
138 DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
139 UINT uiStatus = 0;
140 UINT value= 0;
141 UINT value1 = 0;
142 UCHAR *pvalue;
144 /* Flush the read and cmd queue. */
145 value=( EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH );
146 wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
147 value=0;
148 wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
150 /* Clear the Avail/Full bits. */
151 value=( EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL );
152 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
154 value= dwAddress | ( (dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ );
155 wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
157 while ( dwRetries != 0 )
160 uiStatus = 0;
161 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
162 if(Adapter->device_removed == TRUE)
164 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got Removed.hence exiting from loop...");
165 return -ENODEV;
168 /* If we are reading 16 bytes we want to be sure that the queue
169 * is full before we read. In the other cases we are ok if the
170 * queue has data available */
171 if ( dwNumWords == 4 )
173 if ( ( uiStatus & EEPROM_READ_DATA_FULL ) != 0 )
175 /* Clear the Avail/Full bits - which ever is set. */
176 value = ( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) ) ;
177 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
178 break;
181 else if ( dwNumWords == 1 )
184 if ( ( uiStatus & EEPROM_READ_DATA_AVAIL ) != 0 )
186 /* We just got Avail and we have to read 32bits so we
187 * need this sleep for Cardbus kind of devices. */
188 if (Adapter->chip_id == 0xBECE0210 )
189 udelay(800);
191 /* Clear the Avail/Full bits - which ever is set. */
192 value=( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) );
193 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
194 break;
198 uiStatus = 0;
200 dwRetries--;
201 if(dwRetries == 0)
203 value=0;
204 value1=0;
205 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
206 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
207 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);
208 return STATUS_FAILURE;
210 if( !(dwRetries%RETRIES_PER_DELAY) )
211 msleep(1);
214 for ( dwIndex = 0; dwIndex < dwNumWords ; dwIndex++ )
216 /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */
217 pvalue = (PUCHAR)(pdwData + dwIndex);
219 value =0;
220 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
222 pvalue[0] = value;
224 value = 0;
225 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
227 pvalue[1] = value;
229 value =0;
230 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
232 pvalue[2] = value;
234 value = 0;
235 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
237 pvalue[3] = value;
240 return STATUS_SUCCESS;
241 } /* ReadBeceemEEPROMBulk() */
243 //-----------------------------------------------------------------------------
244 // Procedure: ReadBeceemEEPROM
246 // Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page
247 // reads to do this operation.
249 // Arguments:
250 // Adapter - ptr to Adapter object instance
251 // uiOffset - EEPROM Offset to read the data from.
252 // pBuffer - Pointer to word where data needs to be stored in.
254 // Returns:
255 // OSAL_STATUS_CODE:
256 //-----------------------------------------------------------------------------
258 INT ReadBeceemEEPROM( PMINI_ADAPTER Adapter,
259 DWORD uiOffset,
260 DWORD *pBuffer
263 UINT uiData[8] = {0};
264 UINT uiByteOffset = 0;
265 UINT uiTempOffset = 0;
267 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," ====> ");
269 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
270 uiByteOffset = uiOffset - uiTempOffset;
272 ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
274 /* A word can overlap at most over 2 pages. In that case we read the
275 * next page too. */
276 if ( uiByteOffset > 12 )
278 ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
281 memcpy( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4);
283 return STATUS_SUCCESS;
284 } /* ReadBeceemEEPROM() */
288 INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter)
290 INT Status;
291 unsigned char puMacAddr[6];
293 Status = BeceemNVMRead(Adapter,
294 (PUINT)&puMacAddr[0],
295 INIT_PARAMS_1_MACADDRESS_ADDRESS,
296 MAC_ADDRESS_SIZE);
298 if(Status == STATUS_SUCCESS)
299 memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
301 return Status;
304 //-----------------------------------------------------------------------------
305 // Procedure: BeceemEEPROMBulkRead
307 // Description: Reads the EEPROM and returns the Data.
309 // Arguments:
310 // Adapter - ptr to Adapter object instance
311 // pBuffer - Buffer to store the data read from EEPROM
312 // uiOffset - Offset of EEPROM from where data should be read
313 // uiNumBytes - Number of bytes to be read from the EEPROM.
315 // Returns:
316 // OSAL_STATUS_SUCCESS - if EEPROM read is successful.
317 // <FAILURE> - if failed.
318 //-----------------------------------------------------------------------------
320 INT BeceemEEPROMBulkRead(
321 PMINI_ADAPTER Adapter,
322 PUINT pBuffer,
323 UINT uiOffset,
324 UINT uiNumBytes)
326 UINT uiData[4] = {0};
327 //UINT uiAddress = 0;
328 UINT uiBytesRemaining = uiNumBytes;
329 UINT uiIndex = 0;
330 UINT uiTempOffset = 0;
331 UINT uiExtraBytes = 0;
332 UINT uiFailureRetries = 0;
333 PUCHAR pcBuff = (PUCHAR)pBuffer;
336 if(uiOffset%MAX_RW_SIZE&& uiBytesRemaining)
338 uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
339 uiExtraBytes = uiOffset-uiTempOffset;
340 ReadBeceemEEPROMBulk(Adapter,uiTempOffset,(PUINT)&uiData[0],4);
341 if(uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes))
343 memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes);
345 uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes);
346 uiIndex += (MAX_RW_SIZE - uiExtraBytes);
347 uiOffset += (MAX_RW_SIZE - uiExtraBytes);
349 else
351 memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining);
352 uiIndex += uiBytesRemaining;
353 uiOffset += uiBytesRemaining;
354 uiBytesRemaining = 0;
361 while(uiBytesRemaining && uiFailureRetries != 128)
363 if(Adapter->device_removed )
365 return -1;
368 if(uiBytesRemaining >= MAX_RW_SIZE)
370 /* For the requests more than or equal to 16 bytes, use bulk
371 * read function to make the access faster.
372 * We read 4 Dwords of data */
373 if(0 == ReadBeceemEEPROMBulk(Adapter,uiOffset,&uiData[0],4))
375 memcpy(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE);
376 uiOffset += MAX_RW_SIZE;
377 uiBytesRemaining -= MAX_RW_SIZE;
378 uiIndex += MAX_RW_SIZE;
380 else
382 uiFailureRetries++;
383 mdelay(3);//sleep for a while before retry...
386 else if(uiBytesRemaining >= 4)
388 if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
390 memcpy(pcBuff+uiIndex,&uiData[0],4);
391 uiOffset += 4;
392 uiBytesRemaining -= 4;
393 uiIndex +=4;
395 else
397 uiFailureRetries++;
398 mdelay(3);//sleep for a while before retry...
401 else
402 { // Handle the reads less than 4 bytes...
403 PUCHAR pCharBuff = (PUCHAR)pBuffer;
404 pCharBuff += uiIndex;
405 if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
407 memcpy(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested.
408 uiBytesRemaining = 0;
410 else
412 uiFailureRetries++;
413 mdelay(3);//sleep for a while before retry...
419 return 0;
422 //-----------------------------------------------------------------------------
423 // Procedure: BeceemFlashBulkRead
425 // Description: Reads the FLASH and returns the Data.
427 // Arguments:
428 // Adapter - ptr to Adapter object instance
429 // pBuffer - Buffer to store the data read from FLASH
430 // uiOffset - Offset of FLASH from where data should be read
431 // uiNumBytes - Number of bytes to be read from the FLASH.
433 // Returns:
434 // OSAL_STATUS_SUCCESS - if FLASH read is successful.
435 // <FAILURE> - if failed.
436 //-----------------------------------------------------------------------------
438 static INT BeceemFlashBulkRead(
439 PMINI_ADAPTER Adapter,
440 PUINT pBuffer,
441 UINT uiOffset,
442 UINT uiNumBytes)
444 UINT uiIndex = 0;
445 UINT uiBytesToRead = uiNumBytes;
446 INT Status = 0;
447 UINT uiPartOffset = 0;
448 int bytes;
450 if(Adapter->device_removed )
452 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device Got Removed ");
453 return -ENODEV;
456 //Adding flash Base address
457 // uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
458 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
459 Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
460 return Status;
461 #endif
463 Adapter->SelectedChip = RESET_CHIP_SELECT;
465 if(uiOffset % MAX_RW_SIZE)
467 BcmDoChipSelect(Adapter,uiOffset);
468 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
470 uiBytesToRead = MAX_RW_SIZE - (uiOffset%MAX_RW_SIZE);
471 uiBytesToRead = MIN(uiNumBytes,uiBytesToRead);
473 bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer+uiIndex, uiBytesToRead);
474 if (bytes < 0) {
475 Status = bytes;
476 Adapter->SelectedChip = RESET_CHIP_SELECT;
477 return Status;
480 uiIndex += uiBytesToRead;
481 uiOffset += uiBytesToRead;
482 uiNumBytes -= uiBytesToRead;
485 while(uiNumBytes)
487 BcmDoChipSelect(Adapter,uiOffset);
488 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
490 uiBytesToRead = MIN(uiNumBytes,MAX_RW_SIZE);
492 bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer+uiIndex, uiBytesToRead);
493 if (bytes < 0) {
494 Status = bytes;
495 break;
499 uiIndex += uiBytesToRead;
500 uiOffset += uiBytesToRead;
501 uiNumBytes -= uiBytesToRead;
504 Adapter->SelectedChip = RESET_CHIP_SELECT;
505 return Status;
508 //-----------------------------------------------------------------------------
509 // Procedure: BcmGetFlashSize
511 // Description: Finds the size of FLASH.
513 // Arguments:
514 // Adapter - ptr to Adapter object instance
516 // Returns:
517 // UINT - size of the FLASH Storage.
519 //-----------------------------------------------------------------------------
521 static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter)
523 if(IsFlash2x(Adapter))
524 return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER));
525 else
526 return 32*1024;
531 //-----------------------------------------------------------------------------
532 // Procedure: BcmGetEEPROMSize
534 // Description: Finds the size of EEPROM.
536 // Arguments:
537 // Adapter - ptr to Adapter object instance
539 // Returns:
540 // UINT - size of the EEPROM Storage.
542 //-----------------------------------------------------------------------------
544 static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter)
546 UINT uiData = 0;
547 UINT uiIndex = 0;
550 // if EEPROM is present and already Calibrated,it will have
551 // 'BECM' string at 0th offset.
552 // To find the EEPROM size read the possible boundaries of the
553 // EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will
554 // result in wrap around. So when we get the End of the EEPROM we will
555 // get 'BECM' string which is indeed at offset 0.
557 BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
558 if(uiData == BECM)
560 for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
562 BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
563 if(uiData == BECM)
565 return uiIndex*1024;
569 else
572 // EEPROM may not be present or not programmed
575 uiData = 0xBABEFACE;
576 if(0 == BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&uiData,0,4,TRUE))
578 uiData = 0;
579 for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
581 BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
582 if(uiData == 0xBABEFACE)
584 return uiIndex*1024;
590 return 0;
594 //-----------------------------------------------------------------------------
595 // Procedure: FlashSectorErase
597 // Description: Finds the sector size of the FLASH.
599 // Arguments:
600 // Adapter - ptr to Adapter object instance
601 // addr - sector start address
602 // numOfSectors - number of sectors to be erased.
604 // Returns:
605 // OSAL_STATUS_CODE
607 //-----------------------------------------------------------------------------
610 static INT FlashSectorErase(PMINI_ADAPTER Adapter,
611 UINT addr,
612 UINT numOfSectors)
614 UINT iIndex = 0, iRetries = 0;
615 UINT uiStatus = 0;
616 UINT value;
617 int bytes;
619 for(iIndex=0;iIndex<numOfSectors;iIndex++)
621 value = 0x06000000;
622 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
624 value = (0xd8000000 | (addr & 0xFFFFFF));
625 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
626 iRetries = 0;
630 value = (FLASH_CMD_STATUS_REG_READ << 24);
631 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
633 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
634 return STATUS_FAILURE;
637 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
638 if (bytes < 0) {
639 uiStatus = bytes;
640 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
641 return uiStatus;
643 iRetries++;
644 //After every try lets make the CPU free for 10 ms. generally time taken by the
645 //the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms
646 //won't hamper performance in any case.
647 msleep(10);
648 }while((uiStatus & 0x1) && (iRetries < 400));
650 if(uiStatus & 0x1)
652 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"iRetries crossing the limit of 80000\n");
653 return STATUS_FAILURE;
656 addr += Adapter->uiSectorSize;
658 return 0;
660 //-----------------------------------------------------------------------------
661 // Procedure: flashByteWrite
663 // Description: Performs Byte by Byte write to flash
665 // Arguments:
666 // Adapter - ptr to Adapter object instance
667 // uiOffset - Offset of the flash where data needs to be written to.
668 // pData - Address of Data to be written.
669 // Returns:
670 // OSAL_STATUS_CODE
672 //-----------------------------------------------------------------------------
674 static INT flashByteWrite(
675 PMINI_ADAPTER Adapter,
676 UINT uiOffset,
677 PVOID pData)
680 UINT uiStatus = 0;
681 INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
683 UINT value;
684 ULONG ulData = *(PUCHAR)pData;
685 int bytes;
688 // need not write 0xFF because write requires an erase and erase will
689 // make whole sector 0xFF.
692 if(0xFF == ulData)
694 return STATUS_SUCCESS;
697 // DumpDebug(NVM_RW,("flashWrite ====>\n"));
698 value = (FLASH_CMD_WRITE_ENABLE << 24);
699 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
701 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
702 return STATUS_FAILURE;
704 if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0 )
706 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
707 return STATUS_FAILURE;
709 value = (0x02000000 | (uiOffset & 0xFFFFFF));
710 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
712 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
713 return STATUS_FAILURE;
716 //__udelay(950);
720 value = (FLASH_CMD_STATUS_REG_READ << 24);
721 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
723 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
724 return STATUS_FAILURE;
726 //__udelay(1);
727 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
728 if (bytes < 0) {
729 uiStatus = bytes;
730 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
731 return uiStatus;
733 iRetries--;
734 if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
735 msleep(1);
737 }while((uiStatus & 0x1) && (iRetries >0) );
739 if(uiStatus & 0x1)
741 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
742 return STATUS_FAILURE ;
745 return STATUS_SUCCESS;
750 //-----------------------------------------------------------------------------
751 // Procedure: flashWrite
753 // Description: Performs write to flash
755 // Arguments:
756 // Adapter - ptr to Adapter object instance
757 // uiOffset - Offset of the flash where data needs to be written to.
758 // pData - Address of Data to be written.
759 // Returns:
760 // OSAL_STATUS_CODE
762 //-----------------------------------------------------------------------------
764 static INT flashWrite(
765 PMINI_ADAPTER Adapter,
766 UINT uiOffset,
767 PVOID pData)
770 //UINT uiStatus = 0;
771 //INT iRetries = 0;
772 //UINT uiReadBack = 0;
774 UINT uiStatus = 0;
775 INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
777 UINT value;
778 UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
779 int bytes;
781 // need not write 0xFFFFFFFF because write requires an erase and erase will
782 // make whole sector 0xFFFFFFFF.
784 if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
786 return 0;
789 value = (FLASH_CMD_WRITE_ENABLE << 24);
791 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
793 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
794 return STATUS_FAILURE;
796 if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
798 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
799 return STATUS_FAILURE;
802 //__udelay(950);
805 value = (FLASH_CMD_STATUS_REG_READ << 24);
806 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
808 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
809 return STATUS_FAILURE;
811 //__udelay(1);
812 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
813 if (bytes < 0) {
814 uiStatus = bytes;
815 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
816 return uiStatus;
819 iRetries--;
820 //this will ensure that in there will be no changes in the current path.
821 //currently one rdm/wrm takes 125 us.
822 //Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay)
823 //Hence current implementation cycle will intoduce no delay in current path
824 if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
825 msleep(1);
826 }while((uiStatus & 0x1) && (iRetries > 0));
828 if(uiStatus & 0x1)
830 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
831 return STATUS_FAILURE ;
834 return STATUS_SUCCESS;
837 //-----------------------------------------------------------------------------
838 // Procedure: flashByteWriteStatus
840 // Description: Performs byte by byte write to flash with write done status check
842 // Arguments:
843 // Adapter - ptr to Adapter object instance
844 // uiOffset - Offset of the flash where data needs to be written to.
845 // pData - Address of the Data to be written.
846 // Returns:
847 // OSAL_STATUS_CODE
849 //-----------------------------------------------------------------------------
850 static INT flashByteWriteStatus(
851 PMINI_ADAPTER Adapter,
852 UINT uiOffset,
853 PVOID pData)
855 UINT uiStatus = 0;
856 INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
857 ULONG ulData = *(PUCHAR)pData;
858 UINT value;
859 int bytes;
862 // need not write 0xFFFFFFFF because write requires an erase and erase will
863 // make whole sector 0xFFFFFFFF.
866 if(0xFF == ulData)
868 return STATUS_SUCCESS;
871 // DumpDebug(NVM_RW,("flashWrite ====>\n"));
873 value = (FLASH_CMD_WRITE_ENABLE << 24);
874 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
876 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
877 return STATUS_SUCCESS;
879 if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0)
881 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
882 return STATUS_FAILURE;
884 value = (0x02000000 | (uiOffset & 0xFFFFFF));
885 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
887 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
888 return STATUS_FAILURE;
891 //msleep(1);
895 value = (FLASH_CMD_STATUS_REG_READ << 24);
896 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
898 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
899 return STATUS_FAILURE;
901 //__udelay(1);
902 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
903 if (bytes < 0) {
904 uiStatus = bytes;
905 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
906 return uiStatus;
909 iRetries--;
910 if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
911 msleep(1);
912 }while((uiStatus & 0x1) && (iRetries > 0));
914 if(uiStatus & 0x1)
916 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
917 return STATUS_FAILURE ;
920 return STATUS_SUCCESS;
923 //-----------------------------------------------------------------------------
924 // Procedure: flashWriteStatus
926 // Description: Performs write to flash with write done status check
928 // Arguments:
929 // Adapter - ptr to Adapter object instance
930 // uiOffset - Offset of the flash where data needs to be written to.
931 // pData - Address of the Data to be written.
932 // Returns:
933 // OSAL_STATUS_CODE
935 //-----------------------------------------------------------------------------
937 static INT flashWriteStatus(
938 PMINI_ADAPTER Adapter,
939 UINT uiOffset,
940 PVOID pData)
942 UINT uiStatus = 0;
943 INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
944 //UINT uiReadBack = 0;
945 UINT value;
946 UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
947 int bytes;
950 // need not write 0xFFFFFFFF because write requires an erase and erase will
951 // make whole sector 0xFFFFFFFF.
953 if (!memcmp(pData,uiErasePattern,MAX_RW_SIZE))
955 return 0;
958 value = (FLASH_CMD_WRITE_ENABLE << 24);
959 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
961 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
962 return STATUS_FAILURE;
964 if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
966 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
967 return STATUS_FAILURE;
969 // __udelay(1);
973 value = (FLASH_CMD_STATUS_REG_READ << 24);
974 if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
976 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
977 return STATUS_FAILURE;
979 //__udelay(1);
980 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
981 if (bytes < 0) {
982 uiStatus = bytes;
983 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
984 return uiStatus;
986 iRetries--;
987 //this will ensure that in there will be no changes in the current path.
988 //currently one rdm/wrm takes 125 us.
989 //Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay)
990 //Hence current implementation cycle will intoduce no delay in current path
991 if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
992 msleep(1);
993 }while((uiStatus & 0x1) && (iRetries >0));
995 if(uiStatus & 0x1)
997 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
998 return STATUS_FAILURE ;
1001 return STATUS_SUCCESS;
1004 //-----------------------------------------------------------------------------
1005 // Procedure: BcmRestoreBlockProtectStatus
1007 // Description: Restores the original block protection status.
1009 // Arguments:
1010 // Adapter - ptr to Adapter object instance
1011 // ulWriteStatus -Original status
1012 // Returns:
1013 // <VOID>
1015 //-----------------------------------------------------------------------------
1017 static VOID BcmRestoreBlockProtectStatus(PMINI_ADAPTER Adapter,ULONG ulWriteStatus)
1019 UINT value;
1020 value = (FLASH_CMD_WRITE_ENABLE<< 24);
1021 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1023 udelay(20);
1024 value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
1025 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1026 udelay(20);
1028 //-----------------------------------------------------------------------------
1029 // Procedure: BcmFlashUnProtectBlock
1031 // Description: UnProtects appropriate blocks for writing.
1033 // Arguments:
1034 // Adapter - ptr to Adapter object instance
1035 // uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned.
1036 // Returns:
1037 // ULONG - Status value before UnProtect.
1039 //-----------------------------------------------------------------------------
1040 static ULONG BcmFlashUnProtectBlock(PMINI_ADAPTER Adapter,UINT uiOffset, UINT uiLength)
1042 ULONG ulStatus = 0;
1043 ULONG ulWriteStatus = 0;
1044 UINT value;
1045 uiOffset = uiOffset&0x000FFFFF;
1048 // Implemented only for 1MB Flash parts.
1050 if(FLASH_PART_SST25VF080B == Adapter->ulFlashID)
1053 // Get Current BP status.
1055 value = (FLASH_CMD_STATUS_REG_READ << 24);
1056 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1057 udelay(10);
1059 // Read status will be WWXXYYZZ. We have to take only WW.
1061 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
1062 ulStatus >>= 24;
1063 ulWriteStatus = ulStatus;
1066 // Bits [5-2] give current block level protection status.
1067 // Bit5: BP3 - DONT CARE
1068 // BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4
1069 // 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS
1072 if(ulStatus)
1074 if((uiOffset+uiLength) <= 0x80000)
1077 // Offset comes in lower half of 1MB. Protect the upper half.
1078 // Clear BP1 and BP0 and set BP2.
1080 ulWriteStatus |= (0x4<<2);
1081 ulWriteStatus &= ~(0x3<<2);
1083 else if((uiOffset+uiLength) <= 0xC0000)
1086 // Offset comes below Upper 1/4. Upper 1/4 can be protected.
1087 // Clear BP2 and set BP1 and BP0.
1089 ulWriteStatus |= (0x3<<2);
1090 ulWriteStatus &= ~(0x1<<4);
1092 else if((uiOffset+uiLength) <= 0xE0000)
1095 // Offset comes below Upper 1/8. Upper 1/8 can be protected.
1096 // Clear BP2 and BP0 and set BP1
1098 ulWriteStatus |= (0x1<<3);
1099 ulWriteStatus &= ~(0x5<<2);
1102 else if((uiOffset+uiLength) <= 0xF0000)
1105 // Offset comes below Upper 1/16. Only upper 1/16 can be protected.
1106 // Set BP0 and Clear BP2,BP1.
1108 ulWriteStatus |= (0x1<<2);
1109 ulWriteStatus &= ~(0x3<<3);
1111 else
1114 // Unblock all.
1115 // Clear BP2,BP1 and BP0.
1117 ulWriteStatus &= ~(0x7<<2);
1120 value = (FLASH_CMD_WRITE_ENABLE<< 24);
1121 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1122 udelay(20);
1123 value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
1124 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1125 udelay(20);
1130 return ulStatus;
1132 //-----------------------------------------------------------------------------
1133 // Procedure: BeceemFlashBulkWrite
1135 // Description: Performs write to the flash
1137 // Arguments:
1138 // Adapter - ptr to Adapter object instance
1139 // pBuffer - Data to be written.
1140 // uiOffset - Offset of the flash where data needs to be written to.
1141 // uiNumBytes - Number of bytes to be written.
1142 // bVerify - read verify flag.
1143 // Returns:
1144 // OSAL_STATUS_CODE
1146 //-----------------------------------------------------------------------------
1148 static INT BeceemFlashBulkWrite(
1149 PMINI_ADAPTER Adapter,
1150 PUINT pBuffer,
1151 UINT uiOffset,
1152 UINT uiNumBytes,
1153 BOOLEAN bVerify)
1155 PCHAR pTempBuff = NULL;
1156 PUCHAR pcBuffer = (PUCHAR)pBuffer;
1157 UINT uiIndex = 0;
1158 UINT uiOffsetFromSectStart = 0;
1159 UINT uiSectAlignAddr = 0;
1160 UINT uiCurrSectOffsetAddr = 0;
1161 UINT uiSectBoundary = 0;
1162 UINT uiNumSectTobeRead = 0;
1163 UCHAR ucReadBk[16] = {0};
1164 ULONG ulStatus = 0;
1165 INT Status = STATUS_SUCCESS;
1166 UINT uiTemp = 0;
1167 UINT index = 0;
1168 UINT uiPartOffset = 0;
1170 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1171 Status = bcmflash_raw_write((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
1172 return Status;
1173 #endif
1175 uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
1177 //Adding flash Base address
1178 // uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
1180 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
1181 uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
1182 uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
1184 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
1185 if(NULL == pTempBuff)
1186 goto BeceemFlashBulkWrite_EXIT;
1188 // check if the data to be written is overlapped across sectors
1190 if(uiOffset+uiNumBytes < uiSectBoundary)
1192 uiNumSectTobeRead = 1;
1194 else
1196 // Number of sectors = Last sector start address/First sector start address
1197 uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
1198 if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
1200 uiNumSectTobeRead++;
1203 //Check whether Requested sector is writable or not in case of flash2x write. But if write call is
1204 // for DSD calibration, allow it without checking of sector permission
1206 if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE))
1208 index = 0;
1209 uiTemp = uiNumSectTobeRead ;
1210 while(uiTemp)
1212 if(IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE)
1214 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%X> is not writable",
1215 (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
1216 Status = SECTOR_IS_NOT_WRITABLE;
1217 goto BeceemFlashBulkWrite_EXIT;
1219 uiTemp = uiTemp - 1;
1220 index = index + 1 ;
1223 Adapter->SelectedChip = RESET_CHIP_SELECT;
1224 while(uiNumSectTobeRead)
1226 //do_gettimeofday(&tv1);
1227 //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));
1228 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1230 BcmDoChipSelect(Adapter,uiSectAlignAddr);
1232 if(0 != BeceemFlashBulkRead(Adapter,
1233 (PUINT)pTempBuff,
1234 uiOffsetFromSectStart,
1235 Adapter->uiSectorSize))
1237 Status = -1;
1238 goto BeceemFlashBulkWrite_EXIT;
1241 //do_gettimeofday(&tr);
1242 //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));
1244 ulStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);
1247 if(uiNumSectTobeRead > 1)
1250 memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
1251 pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
1252 uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
1254 else
1256 memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
1259 if(IsFlash2x(Adapter))
1261 SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart);
1264 FlashSectorErase(Adapter,uiPartOffset,1);
1265 //do_gettimeofday(&te);
1266 //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));
1268 for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize)
1270 if(Adapter->device_removed)
1272 Status = -1;
1273 goto BeceemFlashBulkWrite_EXIT;
1275 if(STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter,uiPartOffset+uiIndex,(&pTempBuff[uiIndex])))
1277 Status = -1;
1278 goto BeceemFlashBulkWrite_EXIT;
1282 //do_gettimeofday(&tw);
1283 //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));
1284 for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
1286 if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
1288 if(Adapter->ulFlashWriteSize == 1)
1290 UINT uiReadIndex = 0;
1291 for(uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++)
1293 if(ucReadBk[uiReadIndex] != pTempBuff[uiIndex+uiReadIndex])
1295 if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex+uiReadIndex,&pTempBuff[uiIndex+uiReadIndex]))
1297 Status = STATUS_FAILURE;
1298 goto BeceemFlashBulkWrite_EXIT;
1303 else
1305 if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
1307 if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex]))
1309 Status = STATUS_FAILURE;
1310 goto BeceemFlashBulkWrite_EXIT;
1316 //do_gettimeofday(&twv);
1317 //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));
1320 if(ulStatus)
1322 BcmRestoreBlockProtectStatus(Adapter,ulStatus);
1323 ulStatus = 0;
1326 uiCurrSectOffsetAddr = 0;
1327 uiSectAlignAddr = uiSectBoundary;
1328 uiSectBoundary += Adapter->uiSectorSize;
1329 uiOffsetFromSectStart += Adapter->uiSectorSize;
1330 uiNumSectTobeRead--;
1332 //do_gettimeofday(&tv2);
1333 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000));
1334 //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));
1336 // Cleanup.
1338 BeceemFlashBulkWrite_EXIT:
1339 if(ulStatus)
1341 BcmRestoreBlockProtectStatus(Adapter,ulStatus);
1344 kfree(pTempBuff);
1346 Adapter->SelectedChip = RESET_CHIP_SELECT;
1347 return Status;
1351 //-----------------------------------------------------------------------------
1352 // Procedure: BeceemFlashBulkWriteStatus
1354 // Description: Writes to Flash. Checks the SPI status after each write.
1356 // Arguments:
1357 // Adapter - ptr to Adapter object instance
1358 // pBuffer - Data to be written.
1359 // uiOffset - Offset of the flash where data needs to be written to.
1360 // uiNumBytes - Number of bytes to be written.
1361 // bVerify - read verify flag.
1362 // Returns:
1363 // OSAL_STATUS_CODE
1365 //-----------------------------------------------------------------------------
1367 static INT BeceemFlashBulkWriteStatus(
1368 PMINI_ADAPTER Adapter,
1369 PUINT pBuffer,
1370 UINT uiOffset,
1371 UINT uiNumBytes,
1372 BOOLEAN bVerify)
1374 PCHAR pTempBuff = NULL;
1375 PUCHAR pcBuffer = (PUCHAR)pBuffer;
1376 UINT uiIndex = 0;
1377 UINT uiOffsetFromSectStart = 0;
1378 UINT uiSectAlignAddr = 0;
1379 UINT uiCurrSectOffsetAddr = 0;
1380 UINT uiSectBoundary = 0;
1381 UINT uiNumSectTobeRead = 0;
1382 UCHAR ucReadBk[16] = {0};
1383 ULONG ulStatus = 0;
1384 UINT Status = STATUS_SUCCESS;
1385 UINT uiTemp = 0;
1386 UINT index = 0;
1387 UINT uiPartOffset = 0;
1389 uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
1391 //uiOffset += Adapter->ulFlashCalStart;
1392 //Adding flash Base address
1393 // uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
1395 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
1396 uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
1397 uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
1399 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
1400 if(NULL == pTempBuff)
1401 goto BeceemFlashBulkWriteStatus_EXIT;
1404 // check if the data to be written is overlapped across sectors
1406 if(uiOffset+uiNumBytes < uiSectBoundary)
1408 uiNumSectTobeRead = 1;
1410 else
1412 // Number of sectors = Last sector start address/First sector start address
1413 uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
1414 if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
1416 uiNumSectTobeRead++;
1420 if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE))
1422 index = 0;
1423 uiTemp = uiNumSectTobeRead ;
1424 while(uiTemp)
1426 if(IsOffsetWritable(Adapter,uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE)
1428 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%x> is not writable",
1429 (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
1430 Status = SECTOR_IS_NOT_WRITABLE;
1431 goto BeceemFlashBulkWriteStatus_EXIT;
1433 uiTemp = uiTemp - 1;
1434 index = index + 1 ;
1438 Adapter->SelectedChip = RESET_CHIP_SELECT;
1439 while(uiNumSectTobeRead)
1441 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1443 BcmDoChipSelect(Adapter,uiSectAlignAddr);
1444 if(0 != BeceemFlashBulkRead(Adapter,
1445 (PUINT)pTempBuff,
1446 uiOffsetFromSectStart,
1447 Adapter->uiSectorSize))
1449 Status = -1;
1450 goto BeceemFlashBulkWriteStatus_EXIT;
1453 ulStatus = BcmFlashUnProtectBlock(Adapter,uiOffsetFromSectStart,Adapter->uiSectorSize);
1455 if(uiNumSectTobeRead > 1)
1458 memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
1459 pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
1460 uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
1462 else
1464 memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
1467 if(IsFlash2x(Adapter))
1469 SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart);
1472 FlashSectorErase(Adapter,uiPartOffset,1);
1474 for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize)
1477 if(Adapter->device_removed)
1479 Status = -1;
1480 goto BeceemFlashBulkWriteStatus_EXIT;
1483 if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex]))
1485 Status = -1;
1486 goto BeceemFlashBulkWriteStatus_EXIT;
1490 if(bVerify)
1492 for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
1495 if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
1497 if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
1499 Status = STATUS_FAILURE;
1500 goto BeceemFlashBulkWriteStatus_EXIT;
1508 if(ulStatus)
1510 BcmRestoreBlockProtectStatus(Adapter,ulStatus);
1511 ulStatus = 0;
1514 uiCurrSectOffsetAddr = 0;
1515 uiSectAlignAddr = uiSectBoundary;
1516 uiSectBoundary += Adapter->uiSectorSize;
1517 uiOffsetFromSectStart += Adapter->uiSectorSize;
1518 uiNumSectTobeRead--;
1521 // Cleanup.
1523 BeceemFlashBulkWriteStatus_EXIT:
1524 if(ulStatus)
1526 BcmRestoreBlockProtectStatus(Adapter,ulStatus);
1529 kfree(pTempBuff);
1530 Adapter->SelectedChip = RESET_CHIP_SELECT;
1531 return Status;
1535 //-----------------------------------------------------------------------------
1536 // Procedure: PropagateCalParamsFromEEPROMToMemory
1538 // Description: Dumps the calibration section of EEPROM to DDR.
1540 // Arguments:
1541 // Adapter - ptr to Adapter object instance
1542 // Returns:
1543 // OSAL_STATUS_CODE
1545 //-----------------------------------------------------------------------------
1548 INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter)
1550 PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL);
1551 UINT uiEepromSize = 0;
1552 UINT uiIndex = 0;
1553 UINT uiBytesToCopy = 0;
1554 UINT uiCalStartAddr = EEPROM_CALPARAM_START;
1555 UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1556 UINT value;
1557 INT Status = 0;
1558 if(pBuff == NULL)
1560 return -1;
1563 if(0 != BeceemEEPROMBulkRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET,4))
1566 kfree(pBuff);
1567 return -1;
1570 uiEepromSize >>= 16;
1571 if(uiEepromSize > 1024*1024)
1573 kfree(pBuff);
1574 return -1;
1578 uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
1580 while(uiBytesToCopy)
1582 if(0 != BeceemEEPROMBulkRead(Adapter,(PUINT)pBuff,uiCalStartAddr,uiBytesToCopy))
1584 Status = -1;
1585 break;
1587 wrm(Adapter,uiMemoryLoc,(PCHAR)(((PULONG)pBuff)+uiIndex),uiBytesToCopy);
1588 uiMemoryLoc += uiBytesToCopy;
1589 uiEepromSize -= uiBytesToCopy;
1590 uiCalStartAddr += uiBytesToCopy;
1591 uiIndex += uiBytesToCopy/4;
1592 uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
1595 value = 0xbeadbead;
1596 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-4,&value, sizeof(value));
1597 value = 0xbeadbead;
1598 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-8,&value, sizeof(value));
1599 kfree(pBuff);
1601 return Status;
1605 //-----------------------------------------------------------------------------
1606 // Procedure: PropagateCalParamsFromFlashToMemory
1608 // Description: Dumps the calibration section of EEPROM to DDR.
1610 // Arguments:
1611 // Adapter - ptr to Adapter object instance
1612 // Returns:
1613 // OSAL_STATUS_CODE
1615 //-----------------------------------------------------------------------------
1617 INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter)
1619 PCHAR pBuff, pPtr;
1620 UINT uiEepromSize = 0;
1621 UINT uiBytesToCopy = 0;
1622 //UINT uiIndex = 0;
1623 UINT uiCalStartAddr = EEPROM_CALPARAM_START;
1624 UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1625 UINT value;
1626 INT Status = 0;
1628 // Write the signature first. This will ensure firmware does not access EEPROM.
1630 value = 0xbeadbead;
1631 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
1632 value = 0xbeadbead;
1633 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
1635 if(0 != BeceemNVMRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET, 4))
1637 return -1;
1639 uiEepromSize = ntohl(uiEepromSize);
1640 uiEepromSize >>= 16;
1643 // subtract the auto init section size
1645 uiEepromSize -= EEPROM_CALPARAM_START;
1647 if(uiEepromSize > 1024*1024)
1649 return -1;
1652 pBuff = kmalloc(uiEepromSize, GFP_KERNEL);
1653 if ( pBuff == NULL )
1654 return -1;
1656 if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize))
1658 kfree(pBuff);
1659 return -1;
1662 pPtr = pBuff;
1664 uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
1666 while(uiBytesToCopy)
1668 Status = wrm(Adapter,uiMemoryLoc,(PCHAR)pPtr,uiBytesToCopy);
1669 if(Status)
1671 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrm failed with status :%d",Status);
1672 break;
1675 pPtr += uiBytesToCopy;
1676 uiEepromSize -= uiBytesToCopy;
1677 uiMemoryLoc += uiBytesToCopy;
1678 uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
1681 kfree(pBuff);
1682 return Status;
1686 //-----------------------------------------------------------------------------
1687 // Procedure: BeceemEEPROMReadBackandVerify
1689 // Description: Read back the data written and verifies.
1691 // Arguments:
1692 // Adapter - ptr to Adapter object instance
1693 // pBuffer - Data to be written.
1694 // uiOffset - Offset of the flash where data needs to be written to.
1695 // uiNumBytes - Number of bytes to be written.
1696 // Returns:
1697 // OSAL_STATUS_CODE
1699 //-----------------------------------------------------------------------------
1701 static INT BeceemEEPROMReadBackandVerify(
1702 PMINI_ADAPTER Adapter,
1703 PUINT pBuffer,
1704 UINT uiOffset,
1705 UINT uiNumBytes)
1707 UINT uiRdbk = 0;
1708 UINT uiIndex = 0;
1709 UINT uiData = 0;
1710 UINT auiData[4] = {0};
1712 while(uiNumBytes)
1714 if(Adapter->device_removed )
1716 return -1;
1719 if(uiNumBytes >= MAX_RW_SIZE)
1720 {// for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster.
1721 BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);
1723 if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
1725 // re-write
1726 BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,MAX_RW_SIZE,FALSE);
1727 mdelay(3);
1728 BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);
1730 if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
1732 return -1;
1735 uiOffset += MAX_RW_SIZE;
1736 uiNumBytes -= MAX_RW_SIZE;
1737 uiIndex += 4;
1740 else if(uiNumBytes >= 4)
1742 BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4);
1743 if(uiData != pBuffer[uiIndex])
1745 //re-write
1746 BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,4,FALSE);
1747 mdelay(3);
1748 BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4);
1749 if(uiData != pBuffer[uiIndex])
1751 return -1;
1754 uiOffset += 4;
1755 uiNumBytes -= 4;
1756 uiIndex++;
1759 else
1760 { // Handle the reads less than 4 bytes...
1761 uiData = 0;
1762 memcpy(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes);
1763 BeceemEEPROMBulkRead(Adapter,&uiRdbk,uiOffset,4);
1765 if(memcmp(&uiData, &uiRdbk, uiNumBytes))
1766 return -1;
1768 uiNumBytes = 0;
1773 return 0;
1776 static VOID BcmSwapWord(UINT *ptr1) {
1778 UINT tempval = (UINT)*ptr1;
1779 char *ptr2 = (char *)&tempval;
1780 char *ptr = (char *)ptr1;
1782 ptr[0] = ptr2[3];
1783 ptr[1] = ptr2[2];
1784 ptr[2] = ptr2[1];
1785 ptr[3] = ptr2[0];
1788 //-----------------------------------------------------------------------------
1789 // Procedure: BeceemEEPROMWritePage
1791 // Description: Performs page write (16bytes) to the EEPROM
1793 // Arguments:
1794 // Adapter - ptr to Adapter object instance
1795 // uiData - Data to be written.
1796 // uiOffset - Offset of the EEPROM where data needs to be written to.
1797 // Returns:
1798 // OSAL_STATUS_CODE
1800 //-----------------------------------------------------------------------------
1801 static INT BeceemEEPROMWritePage( PMINI_ADAPTER Adapter, UINT uiData[], UINT uiOffset )
1803 UINT uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
1804 UINT uiStatus = 0;
1805 UCHAR uiEpromStatus = 0;
1806 UINT value =0 ;
1808 /* Flush the Write/Read/Cmd queues. */
1809 value = ( EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH );
1810 wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
1811 value = 0 ;
1812 wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
1814 /* Clear the Empty/Avail/Full bits. After this it has been confirmed
1815 * that the bit was cleared by reading back the register. See NOTE below.
1816 * We also clear the Read queues as we do a EEPROM status register read
1817 * later. */
1818 value = ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL ) ;
1819 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
1821 /* Enable write */
1822 value = EEPROM_WRITE_ENABLE ;
1823 wrmalt( Adapter, EEPROM_CMDQ_SPI_REG,&value, sizeof(value) );
1825 /* We can write back to back 8bits * 16 into the queue and as we have
1826 * checked for the queue to be empty we can write in a burst. */
1828 value = uiData[0];
1829 BcmSwapWord(&value);
1830 wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1832 value = uiData[1];
1833 BcmSwapWord(&value);
1834 wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1836 value = uiData[2];
1837 BcmSwapWord(&value);
1838 wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1840 value = uiData[3];
1841 BcmSwapWord(&value);
1842 wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1844 /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG
1845 * shows that we see 7 for the EEPROM data write. Which means that
1846 * queue got full, also space is available as well as the queue is empty.
1847 * This may happen in sequence. */
1848 value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset ;
1849 wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value) );
1851 /* Ideally we should loop here without tries and eventually succeed.
1852 * What we are checking if the previous write has completed, and this
1853 * may take time. We should wait till the Empty bit is set. */
1854 uiStatus = 0;
1855 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
1856 while ( ( uiStatus & EEPROM_WRITE_QUEUE_EMPTY ) == 0 )
1858 uiRetries--;
1859 if ( uiRetries == 0 )
1861 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY);
1862 return STATUS_FAILURE ;
1865 if( !(uiRetries%RETRIES_PER_DELAY) )
1866 msleep(1);
1868 uiStatus = 0;
1869 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
1870 if(Adapter->device_removed == TRUE)
1872 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem got removed hence exiting from loop....");
1873 return -ENODEV;
1878 if ( uiRetries != 0 )
1880 /* Clear the ones that are set - either, Empty/Full/Avail bits */
1881 value = ( uiStatus & ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL ) );
1882 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
1885 /* Here we should check if the EEPROM status register is correct before
1886 * proceeding. Bit 0 in the EEPROM Status register should be 0 before
1887 * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy
1888 * with the previous write. Note also that issuing this read finally
1889 * means the previous write to the EEPROM has completed. */
1890 uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
1891 uiEpromStatus = 0;
1892 while ( uiRetries != 0 )
1894 uiEpromStatus = ReadEEPROMStatusRegister( Adapter) ;
1895 if(Adapter->device_removed == TRUE)
1897 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
1898 return -ENODEV;
1900 if ( ( EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus ) == 0 )
1902 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY- uiRetries) );
1903 return STATUS_SUCCESS ;
1905 uiRetries--;
1906 if ( uiRetries == 0 )
1908 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);
1909 return STATUS_FAILURE ;
1911 uiEpromStatus = 0;
1912 if( !(uiRetries%RETRIES_PER_DELAY) )
1913 msleep(1);
1916 return STATUS_SUCCESS ;
1917 } /* BeceemEEPROMWritePage */
1920 //-----------------------------------------------------------------------------
1921 // Procedure: BeceemEEPROMBulkWrite
1923 // Description: Performs write to the EEPROM
1925 // Arguments:
1926 // Adapter - ptr to Adapter object instance
1927 // pBuffer - Data to be written.
1928 // uiOffset - Offset of the EEPROM where data needs to be written to.
1929 // uiNumBytes - Number of bytes to be written.
1930 // bVerify - read verify flag.
1931 // Returns:
1932 // OSAL_STATUS_CODE
1934 //-----------------------------------------------------------------------------
1936 INT BeceemEEPROMBulkWrite(
1937 PMINI_ADAPTER Adapter,
1938 PUCHAR pBuffer,
1939 UINT uiOffset,
1940 UINT uiNumBytes,
1941 BOOLEAN bVerify)
1943 UINT uiBytesToCopy = uiNumBytes;
1944 //UINT uiRdbk = 0;
1945 UINT uiData[4] = {0};
1946 UINT uiIndex = 0;
1947 UINT uiTempOffset = 0;
1948 UINT uiExtraBytes = 0;
1949 //PUINT puiBuffer = (PUINT)pBuffer;
1950 //INT value;
1952 if(uiOffset%MAX_RW_SIZE && uiBytesToCopy)
1954 uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
1955 uiExtraBytes = uiOffset-uiTempOffset;
1958 BeceemEEPROMBulkRead(Adapter,&uiData[0],uiTempOffset,MAX_RW_SIZE);
1960 if(uiBytesToCopy >= (16 -uiExtraBytes))
1962 memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes);
1964 if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
1965 return STATUS_FAILURE;
1967 uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes);
1968 uiIndex += (MAX_RW_SIZE - uiExtraBytes);
1969 uiOffset += (MAX_RW_SIZE - uiExtraBytes);
1971 else
1973 memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy);
1975 if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
1976 return STATUS_FAILURE;
1978 uiIndex += uiBytesToCopy;
1979 uiOffset += uiBytesToCopy;
1980 uiBytesToCopy = 0;
1986 while(uiBytesToCopy)
1988 if(Adapter->device_removed)
1990 return -1;
1993 if(uiBytesToCopy >= MAX_RW_SIZE)
1996 if (STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, (PUINT) &pBuffer[uiIndex], uiOffset ) )
1997 return STATUS_FAILURE;
1999 uiIndex += MAX_RW_SIZE;
2000 uiOffset += MAX_RW_SIZE;
2001 uiBytesToCopy -= MAX_RW_SIZE;
2003 else
2006 // To program non 16byte aligned data, read 16byte and then update.
2008 BeceemEEPROMBulkRead(Adapter,&uiData[0],uiOffset,16);
2009 memcpy(&uiData[0],pBuffer+uiIndex,uiBytesToCopy);
2012 if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiOffset ) )
2013 return STATUS_FAILURE;
2014 uiBytesToCopy = 0;
2019 return 0;
2022 //-----------------------------------------------------------------------------
2023 // Procedure: BeceemNVMRead
2025 // Description: Reads n number of bytes from NVM.
2027 // Arguments:
2028 // Adapter - ptr to Adapter object instance
2029 // pBuffer - Buffer to store the data read from NVM
2030 // uiOffset - Offset of NVM from where data should be read
2031 // uiNumBytes - Number of bytes to be read from the NVM.
2033 // Returns:
2034 // OSAL_STATUS_SUCCESS - if NVM read is successful.
2035 // <FAILURE> - if failed.
2036 //-----------------------------------------------------------------------------
2038 INT BeceemNVMRead(
2039 PMINI_ADAPTER Adapter,
2040 PUINT pBuffer,
2041 UINT uiOffset,
2042 UINT uiNumBytes)
2044 INT Status = 0;
2045 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2046 UINT uiTemp = 0, value;
2047 #endif
2049 if(Adapter->eNVMType == NVM_FLASH)
2051 if(Adapter->bFlashRawRead == FALSE)
2053 if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
2054 return vendorextnReadSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes);
2055 uiOffset = uiOffset+ Adapter->ulFlashCalStart ;
2057 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
2058 Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
2059 #else
2061 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2062 value = 0;
2063 wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
2064 Status = BeceemFlashBulkRead(Adapter,
2065 pBuffer,
2066 uiOffset,
2067 uiNumBytes);
2068 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2069 #endif
2071 else if(Adapter->eNVMType == NVM_EEPROM)
2073 Status = BeceemEEPROMBulkRead(Adapter,
2074 pBuffer,
2075 uiOffset,
2076 uiNumBytes);
2078 else
2080 Status = -1;
2082 return Status;
2085 //-----------------------------------------------------------------------------
2086 // Procedure: BeceemNVMWrite
2088 // Description: Writes n number of bytes to NVM.
2090 // Arguments:
2091 // Adapter - ptr to Adapter object instance
2092 // pBuffer - Buffer contains the data to be written.
2093 // uiOffset - Offset of NVM where data to be written to.
2094 // uiNumBytes - Number of bytes to be written..
2096 // Returns:
2097 // OSAL_STATUS_SUCCESS - if NVM write is successful.
2098 // <FAILURE> - if failed.
2099 //-----------------------------------------------------------------------------
2101 INT BeceemNVMWrite(
2102 PMINI_ADAPTER Adapter,
2103 PUINT pBuffer,
2104 UINT uiOffset,
2105 UINT uiNumBytes,
2106 BOOLEAN bVerify)
2108 INT Status = 0;
2109 UINT uiTemp = 0;
2110 UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
2111 UINT uiIndex = 0;
2112 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2113 UINT value;
2114 #endif
2115 UINT uiFlashOffset = 0;
2117 if(Adapter->eNVMType == NVM_FLASH)
2119 if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
2120 Status = vendorextnWriteSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes,bVerify);
2121 else
2123 uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;
2125 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
2126 Status = bcmflash_raw_write((uiFlashOffset/FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer,uiNumBytes);
2127 #else
2128 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2129 value = 0;
2130 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2132 if(Adapter->bStatusWrite == TRUE)
2134 Status = BeceemFlashBulkWriteStatus(Adapter,
2135 pBuffer,
2136 uiFlashOffset,
2137 uiNumBytes ,
2138 bVerify);
2140 else
2143 Status = BeceemFlashBulkWrite(Adapter,
2144 pBuffer,
2145 uiFlashOffset,
2146 uiNumBytes,
2147 bVerify);
2149 #endif
2153 if(uiOffset >= EEPROM_CALPARAM_START)
2155 uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
2156 while(uiNumBytes)
2158 if(uiNumBytes > BUFFER_4K)
2160 wrm(Adapter,(uiMemoryLoc+uiIndex),(PCHAR)(pBuffer+(uiIndex/4)),BUFFER_4K);
2161 uiNumBytes -= BUFFER_4K;
2162 uiIndex += BUFFER_4K;
2164 else
2166 wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)(pBuffer+(uiIndex/4)),uiNumBytes);
2167 uiNumBytes = 0;
2168 break;
2172 else
2174 if((uiOffset+uiNumBytes) > EEPROM_CALPARAM_START)
2176 ULONG ulBytesTobeSkipped = 0;
2177 PUCHAR pcBuffer = (PUCHAR)pBuffer;// char pointer to take care of odd byte cases.
2178 uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
2179 ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
2180 uiOffset += (EEPROM_CALPARAM_START - uiOffset);
2181 while(uiNumBytes)
2183 if(uiNumBytes > BUFFER_4K)
2185 wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR )&pcBuffer[ulBytesTobeSkipped+uiIndex],BUFFER_4K);
2186 uiNumBytes -= BUFFER_4K;
2187 uiIndex += BUFFER_4K;
2189 else
2191 wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)&pcBuffer[ulBytesTobeSkipped+uiIndex],uiNumBytes);
2192 uiNumBytes = 0;
2193 break;
2200 // restore the values.
2201 wrmalt(Adapter,0x0f000C80,&uiTemp, sizeof(uiTemp));
2203 else if(Adapter->eNVMType == NVM_EEPROM)
2205 Status = BeceemEEPROMBulkWrite(Adapter,
2206 (PUCHAR)pBuffer,
2207 uiOffset,
2208 uiNumBytes,
2209 bVerify);
2210 if(bVerify)
2212 Status = BeceemEEPROMReadBackandVerify(Adapter,(PUINT)pBuffer,uiOffset,uiNumBytes);
2215 else
2217 Status = -1;
2219 return Status;
2222 //-----------------------------------------------------------------------------
2223 // Procedure: BcmUpdateSectorSize
2225 // Description: Updates the sector size to FLASH.
2227 // Arguments:
2228 // Adapter - ptr to Adapter object instance
2229 // uiSectorSize - sector size
2231 // Returns:
2232 // OSAL_STATUS_SUCCESS - if NVM write is successful.
2233 // <FAILURE> - if failed.
2234 //-----------------------------------------------------------------------------
2236 INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize)
2238 INT Status = -1;
2239 FLASH_CS_INFO sFlashCsInfo = {0};
2240 UINT uiTemp = 0;
2242 UINT uiSectorSig = 0;
2243 UINT uiCurrentSectorSize = 0;
2245 UINT value;
2249 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2250 value = 0;
2251 wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
2254 // Before updating the sector size in the reserved area, check if already present.
2256 BeceemFlashBulkRead(Adapter,(PUINT)&sFlashCsInfo,Adapter->ulFlashControlSectionStart,sizeof(sFlashCsInfo));
2257 uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
2258 uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);
2260 if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
2263 if((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE))
2265 if(uiSectorSize == uiCurrentSectorSize)
2267 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Provided sector size is same as programmed in Flash");
2268 Status = STATUS_SUCCESS;
2269 goto Restore ;
2274 if((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE))
2277 sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize);
2278 sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG);
2280 Status = BeceemFlashBulkWrite(Adapter,
2281 (PUINT)&sFlashCsInfo,
2282 Adapter->ulFlashControlSectionStart,
2283 sizeof(sFlashCsInfo),
2284 TRUE);
2289 Restore :
2290 // restore the values.
2291 wrmalt(Adapter, 0x0f000C80,&uiTemp, sizeof(uiTemp));
2294 return Status;
2298 //-----------------------------------------------------------------------------
2299 // Procedure: BcmGetFlashSectorSize
2301 // Description: Finds the sector size of the FLASH.
2303 // Arguments:
2304 // Adapter - ptr to Adapter object instance
2306 // Returns:
2307 // UINT - sector size.
2309 //-----------------------------------------------------------------------------
2311 static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize)
2313 UINT uiSectorSize = 0;
2314 UINT uiSectorSig = 0;
2316 if(Adapter->bSectorSizeOverride &&
2317 (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2318 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE))
2320 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2322 else
2325 uiSectorSig = FlashSectorSizeSig;
2327 if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
2329 uiSectorSize = FlashSectorSize;
2331 // If the sector size stored in the FLASH makes sense then use it.
2333 if(uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE)
2335 Adapter->uiSectorSize = uiSectorSize;
2337 //No valid size in FLASH, check if Config file has it.
2338 else if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2339 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
2341 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2343 // Init to Default, if none of the above works.
2344 else
2346 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2350 else
2352 if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2353 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
2355 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2357 else
2359 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2364 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x \n", Adapter->uiSectorSize);
2365 return Adapter->uiSectorSize;
2368 //-----------------------------------------------------------------------------
2369 // Procedure: BcmInitEEPROMQueues
2371 // Description: Initialization of EEPROM queues.
2373 // Arguments:
2374 // Adapter - ptr to Adapter object instance
2376 // Returns:
2377 // <OSAL_STATUS_CODE>
2378 //-----------------------------------------------------------------------------
2380 static INT BcmInitEEPROMQueues(PMINI_ADAPTER Adapter)
2382 UINT value = 0;
2383 /* CHIP Bug : Clear the Avail bits on the Read queue. The default
2384 * value on this register is supposed to be 0x00001102.
2385 * But we get 0x00001122. */
2386 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Fixing reset value on 0x0f003004 register\n" );
2387 value = EEPROM_READ_DATA_AVAIL;
2388 wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
2390 /* Flush the all the EEPROM queues. */
2391 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n");
2392 value =EEPROM_ALL_QUEUE_FLUSH ;
2393 wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
2395 value = 0;
2396 wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
2398 /* Read the EEPROM Status Register. Just to see, no real purpose. */
2399 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter) );
2401 return STATUS_SUCCESS;
2402 } /* BcmInitEEPROMQueues() */
2404 //-----------------------------------------------------------------------------
2405 // Procedure: BcmInitNVM
2407 // Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc.
2409 // Arguments:
2410 // Adapter - ptr to Adapter object instance
2412 // Returns:
2413 // <OSAL_STATUS_CODE>
2414 //-----------------------------------------------------------------------------
2416 INT BcmInitNVM(PMINI_ADAPTER ps_adapter)
2418 BcmValidateNvmType(ps_adapter);
2419 BcmInitEEPROMQueues(ps_adapter);
2421 if(ps_adapter->eNVMType == NVM_AUTODETECT)
2423 ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
2424 if(ps_adapter->eNVMType == NVM_UNKNOWN)
2426 BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
2429 else if(ps_adapter->eNVMType == NVM_FLASH)
2431 BcmGetFlashCSInfo(ps_adapter);
2434 BcmGetNvmSize(ps_adapter);
2436 return STATUS_SUCCESS;
2438 /***************************************************************************/
2439 /*BcmGetNvmSize : set the EEPROM or flash size in Adapter.
2441 *Input Parameter:
2442 * Adapter data structure
2443 *Return Value :
2444 * 0. means success;
2446 /***************************************************************************/
2448 static INT BcmGetNvmSize(PMINI_ADAPTER Adapter)
2450 if(Adapter->eNVMType == NVM_EEPROM)
2452 Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
2454 else if(Adapter->eNVMType == NVM_FLASH)
2456 Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
2458 return 0;
2461 //-----------------------------------------------------------------------------
2462 // Procedure: BcmValidateNvm
2464 // Description: Validates the NVM Type option selected against the device
2466 // Arguments:
2467 // Adapter - ptr to Adapter object instance
2469 // Returns:
2470 // <VOID>
2471 //-----------------------------------------------------------------------------
2472 static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter)
2476 // if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
2477 // Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
2478 // So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
2481 if(Adapter->eNVMType == NVM_FLASH &&
2482 Adapter->chip_id < 0xBECE3300)
2484 Adapter->eNVMType = NVM_AUTODETECT;
2487 //-----------------------------------------------------------------------------
2488 // Procedure: BcmReadFlashRDID
2490 // Description: Reads ID from Serial Flash
2492 // Arguments:
2493 // Adapter - ptr to Adapter object instance
2495 // Returns:
2496 // Flash ID
2497 //-----------------------------------------------------------------------------
2498 static ULONG BcmReadFlashRDID(PMINI_ADAPTER Adapter)
2500 ULONG ulRDID = 0;
2501 UINT value;
2503 // Read ID Instruction.
2505 value = (FLASH_CMD_READ_ID<<24);
2506 wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value));
2508 //Delay
2509 udelay(10);
2511 // Read SPI READQ REG. The output will be WWXXYYZZ.
2512 // The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
2514 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID));
2516 return (ulRDID >>8);
2521 INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
2523 if(psAdapter == NULL)
2525 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
2526 return -EINVAL;
2528 psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL);
2529 if(psAdapter->psFlashCSInfo == NULL)
2531 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 1.x");
2532 return -ENOMEM;
2535 psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL);
2536 if(psAdapter->psFlash2xCSInfo == NULL)
2538 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x");
2539 kfree(psAdapter->psFlashCSInfo);
2540 return -ENOMEM;
2543 psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL);
2544 if(psAdapter->psFlash2xVendorInfo == NULL)
2546 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x");
2547 kfree(psAdapter->psFlashCSInfo);
2548 kfree(psAdapter->psFlash2xCSInfo);
2549 return -ENOMEM;
2552 return STATUS_SUCCESS;
2555 INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
2557 if(psAdapter == NULL)
2559 BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL");
2560 return -EINVAL;
2562 kfree(psAdapter->psFlashCSInfo);
2563 kfree(psAdapter->psFlash2xCSInfo);
2564 kfree(psAdapter->psFlash2xVendorInfo);
2565 return STATUS_SUCCESS ;
2568 static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,PMINI_ADAPTER Adapter)
2570 UINT Index = 0;
2571 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
2572 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber));
2573 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2574 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2575 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
2576 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
2577 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
2578 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
2579 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware ));
2580 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
2581 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
2582 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
2583 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
2584 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
2585 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
2586 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
2587 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
2588 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
2589 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
2590 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
2591 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
2592 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
2593 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
2594 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
2595 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
2596 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
2597 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
2598 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
2599 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
2600 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
2601 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
2602 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
2603 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
2604 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
2605 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
2606 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
2607 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
2608 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
2609 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
2610 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
2611 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
2612 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
2613 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
2614 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
2615 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
2616 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
2617 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
2618 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
2619 for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
2621 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
2622 (psFlash2xCSInfo->SectorAccessBitMap[Index]));
2625 return STATUS_SUCCESS;
2629 static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo)
2631 UINT Index = 0;
2632 psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
2633 psFlash2xCSInfo->FlashLayoutVersion= ntohl(psFlash2xCSInfo->FlashLayoutVersion);
2634 //psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion);
2635 psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
2636 psFlash2xCSInfo->SCSIFirmwareVersion =ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
2637 psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
2638 psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
2639 psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware );
2640 psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
2641 psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
2642 psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
2643 psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
2644 psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
2645 psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
2646 psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
2647 psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
2648 psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
2649 psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
2650 psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
2651 psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
2652 psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
2653 psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
2654 psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
2655 psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
2656 psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
2657 psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
2658 psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
2659 psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
2660 psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
2661 psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
2662 psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
2663 psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
2664 psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
2665 psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
2666 psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
2667 psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
2668 psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
2669 psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
2670 psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
2671 psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
2672 psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
2673 psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
2674 psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
2675 psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
2676 psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
2677 psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
2678 for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
2680 psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
2682 return STATUS_SUCCESS;
2685 static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo)
2687 //UINT Index = 0;
2688 psFlashCSInfo->MagicNumber =ntohl(psFlashCSInfo->MagicNumber);
2689 psFlashCSInfo->FlashLayoutVersion =ntohl(psFlashCSInfo->FlashLayoutVersion);
2690 psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion);
2691 //won't convert according to old assumption
2692 psFlashCSInfo->SCSIFirmwareVersion =(psFlashCSInfo->SCSIFirmwareVersion);
2694 psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
2695 psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
2696 psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware );
2697 psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
2698 psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2699 psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
2700 psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
2701 psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
2702 psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
2703 psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
2704 psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout);
2705 psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature);
2706 psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig);
2707 psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize);
2708 psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize);
2709 psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize);
2710 psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr);
2711 psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize);
2712 psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
2713 psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout);
2715 return STATUS_SUCCESS;
2718 static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
2720 return ( Adapter->uiVendorExtnFlag &&
2721 (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
2722 (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS) );
2725 static VOID UpdateVendorInfo(PMINI_ADAPTER Adapter)
2727 B_UINT32 i = 0;
2728 UINT uiSizeSection = 0;
2730 Adapter->uiVendorExtnFlag = FALSE;
2732 for(i = 0;i < TOTAL_SECTIONS;i++)
2733 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
2735 if(STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
2736 return;
2738 i = 0;
2739 while(i < TOTAL_SECTIONS)
2741 if(!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT))
2743 i++;
2744 continue;
2747 Adapter->uiVendorExtnFlag = TRUE;
2748 uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
2749 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
2751 switch(i)
2753 case DSD0:
2754 if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
2755 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2756 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
2757 else
2758 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
2759 break;
2761 case DSD1:
2762 if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
2763 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2764 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
2765 else
2766 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
2767 break;
2769 case DSD2:
2770 if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
2771 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2772 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
2773 else
2774 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
2775 break;
2776 case VSA0:
2777 if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2778 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
2779 else
2780 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
2781 break;
2783 case VSA1:
2784 if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2785 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
2786 else
2787 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
2788 break;
2789 case VSA2:
2790 if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2791 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
2792 else
2793 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
2794 break;
2796 default:
2797 break;
2799 i++;
2804 //-----------------------------------------------------------------------------
2805 // Procedure: BcmGetFlashCSInfo
2807 // Description: Reads control structure and gets Cal section addresses.
2809 // Arguments:
2810 // Adapter - ptr to Adapter object instance
2812 // Returns:
2813 // <VOID>
2814 //-----------------------------------------------------------------------------
2816 static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter)
2818 //FLASH_CS_INFO sFlashCsInfo = {0};
2820 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2821 UINT value;
2822 #endif
2823 UINT uiFlashLayoutMajorVersion;
2824 Adapter->uiFlashLayoutMinorVersion = 0;
2825 Adapter->uiFlashLayoutMajorVersion = 0;
2826 Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
2829 Adapter->uiFlashBaseAdd = 0;
2830 Adapter->ulFlashCalStart = 0;
2831 memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO));
2832 memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO));
2834 if(!Adapter->bDDRInitDone)
2837 value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
2838 wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
2843 // Reading first 8 Bytes to get the Flash Layout
2844 // MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
2845 BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,8);
2847 Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
2848 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
2849 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion));
2850 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));
2852 if(FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber))
2854 uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2855 Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2857 else
2859 Adapter->uiFlashLayoutMinorVersion = 0;
2860 uiFlashLayoutMajorVersion = 0;
2863 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);
2865 if(uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER)
2867 BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,sizeof(FLASH_CS_INFO));
2868 ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
2869 Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2871 if(!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
2873 Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
2876 if((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) &&
2877 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) &&
2878 (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) &&
2879 (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize)))
2881 Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
2882 Adapter->fpFlashWrite = flashByteWrite;
2883 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2885 else
2887 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2888 Adapter->fpFlashWrite = flashWrite;
2889 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2892 BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
2893 (Adapter->psFlashCSInfo->FlashSectorSize));
2896 Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2900 else
2902 if(BcmFlash2xBulkRead(Adapter,(PUINT)Adapter->psFlash2xCSInfo,NO_SECTION_VAL,
2903 Adapter->ulFlashControlSectionStart,sizeof(FLASH2X_CS_INFO)))
2905 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure \n");
2906 return STATUS_FAILURE;
2908 ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
2909 BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter);
2910 if((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
2911 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
2912 (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
2913 (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize))
2915 Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
2916 Adapter->fpFlashWrite = flashByteWrite;
2917 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2919 else
2921 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2922 Adapter->fpFlashWrite = flashWrite;
2923 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2926 BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
2927 Adapter->psFlash2xCSInfo->FlashSectorSize);
2929 UpdateVendorInfo(Adapter);
2931 BcmGetActiveDSD(Adapter);
2932 BcmGetActiveISO(Adapter);
2933 Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2934 Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;
2938 Concerns: what if CS sector size does not match with this sector size ???
2939 what is the indication of AccessBitMap in CS in flash 2.x ????
2941 Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
2943 Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
2946 return STATUS_SUCCESS ;
2950 //-----------------------------------------------------------------------------
2951 // Procedure: BcmGetNvmType
2953 // Description: Finds the type of NVM used.
2955 // Arguments:
2956 // Adapter - ptr to Adapter object instance
2958 // Returns:
2959 // NVM_TYPE
2961 //-----------------------------------------------------------------------------
2963 static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter)
2965 UINT uiData = 0;
2967 BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
2968 if(uiData == BECM)
2970 return NVM_EEPROM;
2973 // Read control struct and get cal addresses before accessing the flash
2975 BcmGetFlashCSInfo(Adapter);
2977 BeceemFlashBulkRead(Adapter,&uiData,0x0 + Adapter->ulFlashCalStart,4);
2978 if(uiData == BECM)
2980 return NVM_FLASH;
2983 // even if there is no valid signature on EEPROM/FLASH find out if they really exist.
2984 // if exist select it.
2986 if(BcmGetEEPROMSize(Adapter))
2988 return NVM_EEPROM;
2991 //TBD for Flash.
2994 return NVM_UNKNOWN;
2998 * BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
2999 * @Adapter : Drivers Private Data structure
3000 * @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
3002 * Return value:-
3003 * On success it return the start offset of the provided section val
3004 * On Failure -returns STATUS_FAILURE
3007 INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
3010 * Considering all the section for which end offset can be calculated or directly given
3011 * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
3012 * endoffset can't be calculated or given in CS Structure.
3015 INT SectStartOffset = 0 ;
3017 SectStartOffset = INVALID_OFFSET ;
3019 if(IsSectionExistInVendorInfo(Adapter,eFlashSectionVal))
3021 return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
3024 switch(eFlashSectionVal)
3026 case ISO_IMAGE1 :
3027 if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
3028 (IsNonCDLessDevice(Adapter) == FALSE))
3029 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3030 break;
3031 case ISO_IMAGE2 :
3032 if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
3033 (IsNonCDLessDevice(Adapter) == FALSE))
3034 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
3035 break;
3036 case DSD0 :
3037 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
3038 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
3039 break;
3040 case DSD1 :
3041 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
3042 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
3043 break;
3044 case DSD2 :
3045 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
3046 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
3047 break;
3048 case VSA0 :
3049 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
3050 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
3051 break;
3052 case VSA1 :
3053 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
3054 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
3055 break;
3056 case VSA2 :
3057 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
3058 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
3059 break;
3060 case SCSI :
3061 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
3062 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
3063 break;
3064 case CONTROL_SECTION :
3065 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
3066 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
3067 break;
3068 case ISO_IMAGE1_PART2 :
3069 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
3070 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
3071 break;
3072 case ISO_IMAGE1_PART3 :
3073 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
3074 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3075 break;
3076 case ISO_IMAGE2_PART2 :
3077 if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
3078 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
3079 break;
3080 case ISO_IMAGE2_PART3 :
3081 if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
3082 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3083 break;
3084 default :
3085 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
3086 SectStartOffset = INVALID_OFFSET;
3088 return SectStartOffset;
3092 * BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
3093 * @Adapter : Drivers Private Data structure
3094 * @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
3096 * Return value:-
3097 * On success it return the end offset of the provided section val
3098 * On Failure -returns STATUS_FAILURE
3101 INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
3103 INT SectEndOffset = 0 ;
3104 SectEndOffset = INVALID_OFFSET;
3106 if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
3108 return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
3111 switch(eFlash2xSectionVal)
3113 case ISO_IMAGE1 :
3114 if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End!= UNINIT_PTR_IN_CS) &&
3115 (IsNonCDLessDevice(Adapter) == FALSE))
3116 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
3117 break;
3118 case ISO_IMAGE2 :
3119 if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End!= UNINIT_PTR_IN_CS) &&
3120 (IsNonCDLessDevice(Adapter) == FALSE))
3121 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
3122 break;
3123 case DSD0 :
3124 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
3125 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
3126 break;
3127 case DSD1 :
3128 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
3129 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
3130 break;
3131 case DSD2 :
3132 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
3133 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
3134 break;
3135 case VSA0 :
3136 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
3137 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
3138 break;
3139 case VSA1 :
3140 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
3141 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
3142 break;
3143 case VSA2 :
3144 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
3145 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
3146 break;
3147 case SCSI :
3148 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
3149 SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
3150 (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
3151 break;
3152 case CONTROL_SECTION :
3153 //Not Clear So Putting failure. confirm and fix it.
3154 SectEndOffset = STATUS_FAILURE;
3155 case ISO_IMAGE1_PART2 :
3156 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End!= UNINIT_PTR_IN_CS)
3157 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
3158 break;
3159 case ISO_IMAGE1_PART3 :
3160 if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End!= UNINIT_PTR_IN_CS)
3161 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
3162 break;
3163 case ISO_IMAGE2_PART2 :
3164 if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
3165 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
3166 break;
3167 case ISO_IMAGE2_PART3 :
3168 if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End!= UNINIT_PTR_IN_CS)
3169 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
3170 break;
3172 default :
3173 SectEndOffset = INVALID_OFFSET;
3175 return SectEndOffset ;
3179 * BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
3180 * @Adapter :Driver Private Data Structure
3181 * @pBuffer : Buffer where data has to be put after reading
3182 * @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
3183 * @uiOffsetWithinSectionVal :- Offset with in provided section
3184 * @uiNumBytes : Number of Bytes for Read
3186 * Return value:-
3187 * return true on success and STATUS_FAILURE on fail.
3190 INT BcmFlash2xBulkRead(
3191 PMINI_ADAPTER Adapter,
3192 PUINT pBuffer,
3193 FLASH2X_SECTION_VAL eFlash2xSectionVal,
3194 UINT uiOffsetWithinSectionVal,
3195 UINT uiNumBytes)
3198 INT Status = STATUS_SUCCESS;
3199 INT SectionStartOffset = 0;
3200 UINT uiAbsoluteOffset = 0 ;
3201 UINT uiTemp =0, value =0 ;
3202 if(Adapter == NULL)
3204 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
3205 return -EINVAL;
3207 if(Adapter->device_removed )
3209 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
3210 return -ENODEV;
3213 //NO_SECTION_VAL means absolute offset is given.
3214 if(eFlash2xSectionVal == NO_SECTION_VAL)
3215 SectionStartOffset = 0;
3216 else
3217 SectionStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
3219 if(SectionStartOffset == STATUS_FAILURE )
3221 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash 2.x Map ",eFlash2xSectionVal);
3222 return -EINVAL;
3225 if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
3226 return vendorextnReadSection(Adapter,(PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
3228 //calculating the absolute offset from FLASH;
3229 uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
3230 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3231 value = 0;
3232 wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
3234 Status= BeceemFlashBulkRead(Adapter, pBuffer,uiAbsoluteOffset,uiNumBytes) ;
3236 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3237 if(Status)
3239 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
3240 return Status ;
3243 return Status;
3247 * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
3248 * @Adapter :Driver Private Data Structure
3249 * @pBuffer : Buffer From where data has to taken for writing
3250 * @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
3251 * @uiOffsetWithinSectionVal :- Offset with in provided section
3252 * @uiNumBytes : Number of Bytes for Write
3254 * Return value:-
3255 * return true on success and STATUS_FAILURE on fail.
3259 INT BcmFlash2xBulkWrite(
3260 PMINI_ADAPTER Adapter,
3261 PUINT pBuffer,
3262 FLASH2X_SECTION_VAL eFlash2xSectVal,
3263 UINT uiOffset,
3264 UINT uiNumBytes,
3265 UINT bVerify)
3268 INT Status = STATUS_SUCCESS;
3269 UINT FlashSectValStartOffset = 0;
3270 UINT uiTemp = 0, value = 0;
3271 if(Adapter == NULL)
3273 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
3274 return -EINVAL;
3276 if(Adapter->device_removed )
3278 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
3279 return -ENODEV;
3282 //NO_SECTION_VAL means absolute offset is given.
3283 if(eFlash2xSectVal == NO_SECTION_VAL)
3284 FlashSectValStartOffset = 0;
3285 else
3286 FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectVal);
3288 if(FlashSectValStartOffset == STATUS_FAILURE )
3290 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash Map 2.x",eFlash2xSectVal);
3291 return -EINVAL;
3294 if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectVal))
3295 return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
3297 //calculating the absolute offset from FLASH;
3298 uiOffset = uiOffset + FlashSectValStartOffset;
3300 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3301 value = 0;
3302 wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
3304 Status = BeceemFlashBulkWrite(Adapter, pBuffer,uiOffset,uiNumBytes,bVerify);
3306 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
3307 if(Status)
3309 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
3310 return Status ;
3313 return Status;
3318 * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
3319 * @Adapter :-Drivers private Data Structure
3321 * Return Value:-
3322 * Return STATUS_SUCESS if get success in setting the right DSD else negaive error code
3325 static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter)
3327 FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
3329 uiHighestPriDSD = getHighestPriDSD(Adapter);
3330 Adapter->eActiveDSD = uiHighestPriDSD;
3332 if(DSD0 == uiHighestPriDSD)
3333 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
3334 if(DSD1 == uiHighestPriDSD)
3335 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
3336 if(DSD2 == uiHighestPriDSD)
3337 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
3338 if(Adapter->eActiveDSD)
3339 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
3340 if(Adapter->eActiveDSD == 0)
3342 //if No DSD gets Active, Make Active the DSD with WR permission
3343 if(IsSectionWritable(Adapter,DSD2))
3345 Adapter->eActiveDSD = DSD2;
3346 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
3348 else if(IsSectionWritable(Adapter,DSD1))
3350 Adapter->eActiveDSD = DSD1;
3351 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
3353 else if(IsSectionWritable(Adapter,DSD0))
3355 Adapter->eActiveDSD = DSD0;
3356 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
3360 return STATUS_SUCCESS;
3365 * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
3366 * @Adapter : Driver private Data Structure
3368 * Return Value:-
3369 * Sucsess:- STATUS_SUCESS
3370 * Failure- : negative erro code
3374 static INT BcmGetActiveISO(PMINI_ADAPTER Adapter)
3377 INT HighestPriISO = 0 ;
3378 HighestPriISO = getHighestPriISO(Adapter);
3380 Adapter->eActiveISO = HighestPriISO ;
3381 if(Adapter->eActiveISO == ISO_IMAGE2)
3382 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
3383 else if(Adapter->eActiveISO == ISO_IMAGE1)
3384 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3386 if(Adapter->eActiveISO)
3387 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Active ISO :%x", Adapter->eActiveISO);
3389 return STATUS_SUCCESS;
3393 * IsOffsetWritable :- it will tell the access permission of the sector having passed offset
3394 * @Adapter : Drivers Private Data Structure
3395 * @uiOffset : Offset provided in the Flash
3397 * Return Value:-
3398 * Success:-TRUE , offset is writable
3399 * Failure:-FALSE, offset is RO
3402 B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset)
3404 UINT uiSectorNum = 0;
3405 UINT uiWordOfSectorPermission =0;
3406 UINT uiBitofSectorePermission = 0;
3407 B_UINT32 permissionBits = 0;
3408 uiSectorNum = uiOffset/Adapter->uiSectorSize;
3410 //calculating the word having this Sector Access permission from SectorAccessBitMap Array
3411 uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum /16];
3413 //calculating the bit index inside the word for this sector
3414 uiBitofSectorePermission = 2*(15 - uiSectorNum %16);
3416 //Setting Access permission
3417 permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission) ;
3418 permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
3419 if(permissionBits == SECTOR_READWRITE_PERMISSION)
3420 return TRUE;
3421 else
3422 return FALSE;
3425 static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
3427 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
3428 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
3429 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1);
3430 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2);
3431 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD0 :0X%x", psFlash2xBitMap->DSD0);
3432 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD1 :0X%x", psFlash2xBitMap->DSD1);
3433 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD2 :0X%x", psFlash2xBitMap->DSD2);
3434 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA0 :0X%x", psFlash2xBitMap->VSA0);
3435 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA1 :0X%x", psFlash2xBitMap->VSA1);
3436 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA2 :0X%x", psFlash2xBitMap->VSA2);
3437 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"SCSI :0X%x", psFlash2xBitMap->SCSI);
3438 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION);
3440 return STATUS_SUCCESS;
3444 * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
3445 * 8bit has been assigned to every section.
3446 bit[0] :Section present or not
3447 bit[1] :section is valid or not
3448 bit[2] : Secton is read only or has write permission too.
3449 bit[3] : Active Section -
3450 bit[7...4] = Reserved .
3452 @Adapter:-Driver private Data Structure
3454 * Return value:-
3455 * Success:- STATUS_SUCESS
3456 * Failure:- negative error code
3459 INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap)
3463 PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
3464 FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
3465 FLASH2X_SECTION_VAL uiHighestPriISO= 0 ;
3466 BOOLEAN SetActiveDSDDone = FALSE ;
3467 BOOLEAN SetActiveISODone = FALSE ;
3469 //For 1.x map all the section except DSD0 will be shown as not present
3470 //This part will be used by calibration tool to detect the number of DSD present in Flash.
3471 if(IsFlash2x(Adapter) == FALSE)
3473 psFlash2xBitMap->ISO_IMAGE2 = 0;
3474 psFlash2xBitMap->ISO_IMAGE1 = 0;
3475 psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF; //0000(Reseved)1(Active)0(RW)1(valid)1(present)
3476 psFlash2xBitMap->DSD1 = 0 ;
3477 psFlash2xBitMap->DSD2 = 0 ;
3478 psFlash2xBitMap->VSA0 = 0 ;
3479 psFlash2xBitMap->VSA1 = 0 ;
3480 psFlash2xBitMap->VSA2 = 0 ;
3481 psFlash2xBitMap->CONTROL_SECTION = 0 ;
3482 psFlash2xBitMap->SCSI= 0 ;
3483 psFlash2xBitMap->Reserved0 = 0 ;
3484 psFlash2xBitMap->Reserved1 = 0 ;
3485 psFlash2xBitMap->Reserved2 = 0 ;
3486 return STATUS_SUCCESS ;
3490 uiHighestPriDSD = getHighestPriDSD(Adapter);
3491 uiHighestPriISO = getHighestPriISO(Adapter);
3494 // IS0 IMAGE 2
3496 if((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS)
3498 //Setting the 0th Bit representing the Section is present or not.
3499 psFlash2xBitMap->ISO_IMAGE2= psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
3502 if(ReadISOSignature(Adapter,ISO_IMAGE2)== ISO_IMAGE_MAGIC_NUMBER)
3503 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
3506 //Calculation for extrating the Access permission
3507 if(IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
3508 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
3510 if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2)
3512 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT ;
3513 SetActiveISODone = TRUE;
3519 // IS0 IMAGE 1
3521 if((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS)
3523 //Setting the 0th Bit representing the Section is present or not.
3524 psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
3526 if(ReadISOSignature(Adapter,ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
3527 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
3529 // Calculation for extrating the Access permission
3530 if(IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
3531 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
3533 if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1)
3535 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT ;
3536 SetActiveISODone = TRUE;
3543 // DSD2
3545 if((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS)
3547 //Setting the 0th Bit representing the Section is present or not.
3548 psFlash2xBitMap->DSD2= psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
3550 if(ReadDSDSignature(Adapter,DSD2)== DSD_IMAGE_MAGIC_NUMBER)
3551 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
3553 //Calculation for extrating the Access permission
3554 if(IsSectionWritable(Adapter, DSD2) == FALSE)
3556 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
3559 else
3561 //Means section is writable
3562 if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2))
3564 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT ;
3565 SetActiveDSDDone =TRUE ;
3571 // DSD 1
3573 if((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS)
3575 //Setting the 0th Bit representing the Section is present or not.
3576 psFlash2xBitMap->DSD1= psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
3579 if(ReadDSDSignature(Adapter,DSD1)== DSD_IMAGE_MAGIC_NUMBER)
3580 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
3582 //Calculation for extrating the Access permission
3583 if(IsSectionWritable(Adapter, DSD1) == FALSE)
3585 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
3587 else
3589 //Means section is writable
3590 if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1))
3592 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT ;
3593 SetActiveDSDDone =TRUE ;
3600 //For DSD 0
3602 if((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS)
3604 //Setting the 0th Bit representing the Section is present or not.
3605 psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
3607 if(ReadDSDSignature(Adapter,DSD0) == DSD_IMAGE_MAGIC_NUMBER)
3608 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
3610 //Setting Access permission
3611 if(IsSectionWritable(Adapter, DSD0) == FALSE)
3613 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
3615 else
3617 //Means section is writable
3618 if((SetActiveDSDDone == FALSE) &&(uiHighestPriDSD == DSD0))
3620 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT ;
3621 SetActiveDSDDone =TRUE ;
3627 // VSA 0
3629 if((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS)
3631 //Setting the 0th Bit representing the Section is present or not.
3632 psFlash2xBitMap->VSA0= psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
3634 //Setting the Access Bit. Map is not defined hece setting it always valid
3635 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
3637 //Calculation for extrating the Access permission
3638 if(IsSectionWritable(Adapter, VSA0) == FALSE)
3639 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO;
3641 //By Default section is Active
3642 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT ;
3648 // VSA 1
3651 if((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS)
3653 //Setting the 0th Bit representing the Section is present or not.
3654 psFlash2xBitMap->VSA1= psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
3656 //Setting the Access Bit. Map is not defined hece setting it always valid
3657 psFlash2xBitMap->VSA1|= FLASH2X_SECTION_VALID;
3659 //Checking For Access permission
3660 if(IsSectionWritable(Adapter, VSA1) == FALSE)
3661 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
3663 //By Default section is Active
3664 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT ;
3670 // VSA 2
3673 if((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS)
3675 //Setting the 0th Bit representing the Section is present or not.
3676 psFlash2xBitMap->VSA2= psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
3679 //Setting the Access Bit. Map is not defined hece setting it always valid
3680 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
3682 //Checking For Access permission
3683 if(IsSectionWritable(Adapter, VSA2) == FALSE)
3684 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
3686 //By Default section is Active
3687 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT ;
3691 // SCSI Section
3693 if((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS)
3695 //Setting the 0th Bit representing the Section is present or not.
3696 psFlash2xBitMap->SCSI= psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
3699 //Setting the Access Bit. Map is not defined hece setting it always valid
3700 psFlash2xBitMap->SCSI|= FLASH2X_SECTION_VALID;
3702 //Checking For Access permission
3703 if(IsSectionWritable(Adapter, SCSI) == FALSE)
3704 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
3706 //By Default section is Active
3707 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT ;
3713 // Control Section
3715 if((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS)
3717 //Setting the 0th Bit representing the Section is present or not.
3718 psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
3721 //Setting the Access Bit. Map is not defined hece setting it always valid
3722 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
3724 //Checking For Access permission
3725 if(IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
3726 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
3728 //By Default section is Active
3729 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT ;
3734 // For Reserved Sections
3736 psFlash2xBitMap->Reserved0 = 0;
3737 psFlash2xBitMap->Reserved0 = 0;
3738 psFlash2xBitMap->Reserved0 = 0;
3740 BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
3742 return STATUS_SUCCESS ;
3746 BcmSetActiveSection :- Set Active section is used to make priority field highest over other
3747 section of same type.
3749 @Adapater :- Bcm Driver Private Data Structure
3750 @eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
3752 Return Value:- Make the priorit highest else return erorr code
3755 INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal)
3757 unsigned int SectImagePriority = 0;
3758 INT Status =STATUS_SUCCESS;
3760 //DSD_HEADER sDSD = {0};
3761 //ISO_HEADER sISO = {0};
3762 INT HighestPriDSD = 0 ;
3763 INT HighestPriISO = 0;
3767 Status = IsSectionWritable(Adapter,eFlash2xSectVal) ;
3768 if(Status != TRUE )
3770 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section <%d> is not writable",eFlash2xSectVal);
3771 return STATUS_FAILURE;
3774 Adapter->bHeaderChangeAllowed = TRUE ;
3775 switch(eFlash2xSectVal)
3777 case ISO_IMAGE1 :
3778 case ISO_IMAGE2 :
3779 if(ReadISOSignature(Adapter,eFlash2xSectVal)== ISO_IMAGE_MAGIC_NUMBER )
3781 HighestPriISO = getHighestPriISO(Adapter);
3783 if(HighestPriISO == eFlash2xSectVal )
3785 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal );
3786 Status = STATUS_SUCCESS ;
3787 break;
3790 SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
3792 if((SectImagePriority <= 0) && IsSectionWritable(Adapter,HighestPriISO))
3794 // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
3795 // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
3796 // by user
3797 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
3798 SectImagePriority = htonl(0x1);
3799 Status = BcmFlash2xBulkWrite(Adapter,
3800 &SectImagePriority,
3801 HighestPriISO,
3802 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
3803 SIGNATURE_SIZE,
3804 TRUE);
3806 if(Status)
3808 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
3809 Status = STATUS_FAILURE;
3810 break ;
3813 HighestPriISO = getHighestPriISO(Adapter);
3815 if(HighestPriISO == eFlash2xSectVal )
3817 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal );
3818 Status = STATUS_SUCCESS ;
3819 break;
3822 SectImagePriority = 2;
3826 SectImagePriority = htonl(SectImagePriority);
3828 Status = BcmFlash2xBulkWrite(Adapter,
3829 &SectImagePriority,
3830 eFlash2xSectVal,
3831 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
3832 SIGNATURE_SIZE,
3833 TRUE);
3834 if(Status)
3836 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
3837 break ;
3840 else
3842 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3843 Status = STATUS_FAILURE ;
3844 break;
3846 break;
3847 case DSD0 :
3848 case DSD1 :
3849 case DSD2 :
3850 if(ReadDSDSignature(Adapter,eFlash2xSectVal)== DSD_IMAGE_MAGIC_NUMBER)
3852 HighestPriDSD = getHighestPriDSD(Adapter);
3854 if((HighestPriDSD == eFlash2xSectVal))
3856 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given DSD<%x> already has highest priority", eFlash2xSectVal);
3857 Status = STATUS_SUCCESS ;
3858 break;
3861 SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1 ;
3862 if(SectImagePriority <= 0)
3864 // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
3865 // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
3866 // by user
3867 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
3868 SectImagePriority = htonl(0x1);
3870 Status = BcmFlash2xBulkWrite(Adapter,
3871 &SectImagePriority,
3872 HighestPriDSD,
3873 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3874 SIGNATURE_SIZE,
3875 TRUE);
3877 if(Status)
3879 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3880 break ;
3883 HighestPriDSD = getHighestPriDSD(Adapter);
3885 if((HighestPriDSD == eFlash2xSectVal))
3887 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
3888 Status = STATUS_SUCCESS ;
3889 break;
3892 SectImagePriority = htonl(0x2);
3893 Status = BcmFlash2xBulkWrite(Adapter,
3894 &SectImagePriority,
3895 HighestPriDSD,
3896 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3897 SIGNATURE_SIZE,
3898 TRUE);
3900 if(Status)
3902 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3903 break ;
3906 HighestPriDSD = getHighestPriDSD(Adapter);
3908 if((HighestPriDSD == eFlash2xSectVal))
3910 Status = STATUS_SUCCESS ;
3911 break;
3913 SectImagePriority = 3 ;
3916 SectImagePriority = htonl(SectImagePriority);
3917 Status = BcmFlash2xBulkWrite(Adapter,
3918 &SectImagePriority,
3919 eFlash2xSectVal,
3920 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3921 SIGNATURE_SIZE ,
3922 TRUE);
3923 if(Status)
3925 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
3926 Status = STATUS_FAILURE ;
3927 break ;
3930 else
3932 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3933 Status = STATUS_FAILURE ;
3934 break;
3936 break;
3937 case VSA0 :
3938 case VSA1 :
3939 case VSA2 :
3940 //Has to be decided
3941 break ;
3942 default :
3943 Status = STATUS_FAILURE ;
3944 break;
3948 Adapter->bHeaderChangeAllowed = FALSE ;
3949 return Status;
3954 BcmCopyISO - Used only for copying the ISO section
3955 @Adapater :- Bcm Driver Private Data Structure
3956 @sCopySectStrut :- Section copy structure
3958 Return value:- SUCCESS if copies successfully else negative error code
3961 INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
3964 PCHAR Buff = NULL;
3965 FLASH2X_SECTION_VAL eISOReadPart = 0,eISOWritePart = 0;
3966 UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
3967 UINT uiTotalDataToCopy = 0;
3968 BOOLEAN IsThisHeaderSector = FALSE ;
3969 UINT sigOffset = 0;
3970 UINT ISOLength = 0;
3971 UINT Status = STATUS_SUCCESS;
3972 UINT SigBuff[MAX_RW_SIZE];
3973 UINT i = 0;
3975 if(ReadISOSignature(Adapter,sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER)
3977 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3978 return STATUS_FAILURE;
3981 Status = BcmFlash2xBulkRead(Adapter,
3982 &ISOLength,
3983 sCopySectStrut.SrcSection,
3984 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageSize),
3987 if(Status)
3989 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
3990 return Status;
3993 ISOLength = htonl(ISOLength);
3995 if(ISOLength % Adapter->uiSectorSize)
3997 ISOLength = Adapter->uiSectorSize*(1 + ISOLength/Adapter->uiSectorSize);
4000 sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);
4002 Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
4004 if(Buff == NULL)
4006 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for section size");
4007 return -ENOMEM;
4010 if(sCopySectStrut.SrcSection ==ISO_IMAGE1 && sCopySectStrut.DstSection ==ISO_IMAGE2)
4012 eISOReadPart = ISO_IMAGE1 ;
4013 eISOWritePart = ISO_IMAGE2 ;
4014 uiReadOffsetWithinPart = 0;
4015 uiWriteOffsetWithinPart = 0 ;
4017 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
4018 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
4019 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
4020 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
4021 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
4022 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
4024 if(uiTotalDataToCopy < ISOLength)
4026 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
4027 Status = STATUS_FAILURE;
4028 goto out;
4031 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
4032 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
4033 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
4034 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
4035 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
4036 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
4038 if(uiTotalDataToCopy < ISOLength)
4040 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
4041 Status = STATUS_FAILURE;
4042 goto out;
4045 uiTotalDataToCopy = ISOLength;
4047 CorruptISOSig(Adapter,ISO_IMAGE2);
4049 while(uiTotalDataToCopy)
4051 if(uiTotalDataToCopy == Adapter->uiSectorSize)
4053 //Setting for write of first sector. First sector is assumed to be written in last
4054 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
4055 eISOReadPart = ISO_IMAGE1 ;
4056 uiReadOffsetWithinPart = 0;
4057 eISOWritePart = ISO_IMAGE2;
4058 uiWriteOffsetWithinPart = 0 ;
4059 IsThisHeaderSector = TRUE ;
4062 else
4064 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
4065 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
4067 if((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) ))
4069 eISOReadPart = ISO_IMAGE1_PART2 ;
4070 uiReadOffsetWithinPart = 0;
4072 if((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
4074 eISOReadPart = ISO_IMAGE1_PART3 ;
4075 uiReadOffsetWithinPart = 0;
4077 if((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)))
4079 eISOWritePart = ISO_IMAGE2_PART2 ;
4080 uiWriteOffsetWithinPart = 0;
4082 if((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
4084 eISOWritePart = ISO_IMAGE2_PART3 ;
4085 uiWriteOffsetWithinPart = 0;
4089 Status = BcmFlash2xBulkRead(Adapter,
4090 (PUINT)Buff,
4091 eISOReadPart,
4092 uiReadOffsetWithinPart,
4093 Adapter->uiSectorSize
4096 if(Status)
4098 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
4099 break;
4102 if(IsThisHeaderSector == TRUE)
4104 //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
4105 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
4107 for(i = 0; i < MAX_RW_SIZE;i++)
4108 *(Buff + sigOffset + i) = 0xFF;
4110 Adapter->bHeaderChangeAllowed = TRUE ;
4112 Status = BcmFlash2xBulkWrite(Adapter,
4113 (PUINT)Buff,
4114 eISOWritePart,
4115 uiWriteOffsetWithinPart,
4116 Adapter->uiSectorSize,
4117 TRUE);
4118 if(Status)
4120 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
4121 break;
4124 Adapter->bHeaderChangeAllowed = FALSE;
4126 if(IsThisHeaderSector == TRUE)
4128 WriteToFlashWithoutSectorErase(Adapter,
4129 SigBuff,
4130 eISOWritePart,
4131 sigOffset,
4132 MAX_RW_SIZE);
4133 IsThisHeaderSector = FALSE ;
4135 //subtracting the written Data
4136 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
4142 if(sCopySectStrut.SrcSection ==ISO_IMAGE2 && sCopySectStrut.DstSection ==ISO_IMAGE1)
4144 eISOReadPart = ISO_IMAGE2 ;
4145 eISOWritePart = ISO_IMAGE1 ;
4146 uiReadOffsetWithinPart = 0;
4147 uiWriteOffsetWithinPart = 0 ;
4149 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
4150 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
4151 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
4152 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
4153 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
4154 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
4156 if(uiTotalDataToCopy < ISOLength)
4158 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
4159 Status = STATUS_FAILURE;
4160 goto out;
4163 uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
4164 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
4165 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
4166 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
4167 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
4168 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
4170 if(uiTotalDataToCopy < ISOLength)
4172 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
4173 Status = STATUS_FAILURE;
4174 goto out;
4177 uiTotalDataToCopy = ISOLength;
4179 CorruptISOSig(Adapter,ISO_IMAGE1);
4181 while(uiTotalDataToCopy)
4183 if(uiTotalDataToCopy == Adapter->uiSectorSize)
4185 //Setting for write of first sector. First sector is assumed to be written in last
4186 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
4187 eISOReadPart = ISO_IMAGE2 ;
4188 uiReadOffsetWithinPart = 0;
4189 eISOWritePart = ISO_IMAGE1;
4190 uiWriteOffsetWithinPart = 0 ;
4191 IsThisHeaderSector = TRUE;
4194 else
4196 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
4197 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
4199 if((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) ))
4201 eISOReadPart = ISO_IMAGE2_PART2 ;
4202 uiReadOffsetWithinPart = 0;
4204 if((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
4206 eISOReadPart = ISO_IMAGE2_PART3 ;
4207 uiReadOffsetWithinPart = 0;
4209 if((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)))
4211 eISOWritePart = ISO_IMAGE1_PART2 ;
4212 uiWriteOffsetWithinPart = 0;
4214 if((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
4216 eISOWritePart = ISO_IMAGE1_PART3 ;
4217 uiWriteOffsetWithinPart = 0;
4221 Status = BcmFlash2xBulkRead(Adapter,
4222 (PUINT)Buff,
4223 eISOReadPart,
4224 uiReadOffsetWithinPart,
4225 Adapter->uiSectorSize
4227 if(Status)
4229 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
4230 break;
4233 if(IsThisHeaderSector == TRUE)
4235 //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
4236 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
4238 for(i = 0; i < MAX_RW_SIZE;i++)
4239 *(Buff + sigOffset + i) = 0xFF;
4242 Adapter->bHeaderChangeAllowed = TRUE ;
4243 Status = BcmFlash2xBulkWrite(Adapter,
4244 (PUINT)Buff,
4245 eISOWritePart,
4246 uiWriteOffsetWithinPart,
4247 Adapter->uiSectorSize,
4248 TRUE);
4250 if(Status)
4252 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
4253 break;
4256 Adapter->bHeaderChangeAllowed = FALSE ;
4258 if(IsThisHeaderSector == TRUE)
4260 WriteToFlashWithoutSectorErase(Adapter,
4261 SigBuff,
4262 eISOWritePart,
4263 sigOffset,
4264 MAX_RW_SIZE);
4265 IsThisHeaderSector = FALSE ;
4268 //subtracting the written Data
4269 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
4275 out:
4276 kfree(Buff);
4278 return Status;
4281 BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
4282 It will corrupt the sig, if Section is writable, by making first bytes as zero.
4283 @Adapater :- Bcm Driver Private Data Structure
4284 @eFlash2xSectionVal :- Flash section val which has header
4286 Return Value :-
4287 Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
4288 Failure :-Return negative error code
4292 INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
4295 INT Status = STATUS_SUCCESS ;
4296 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Section Value :%x \n", eFlash2xSectionVal);
4298 if((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2))
4300 Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
4302 else if(eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2)
4304 Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
4306 else
4308 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given Section <%d>does not have Header",eFlash2xSectionVal);
4309 return STATUS_SUCCESS;
4311 return Status;
4314 BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
4315 header and Write Permission.
4316 @Adapater :- Bcm Driver Private Data Structure
4317 @eFlashSectionVal :- Flash section val which has header
4319 Return Value :-
4320 Success :- If Section is present and writable write the sig and return STATUS_SUCCESS
4321 Failure :-Return negative error code
4324 INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
4327 UINT uiSignature = 0 ;
4328 UINT uiOffset = 0;
4329 //DSD_HEADER dsdHeader = {0};
4331 if(Adapter->bSigCorrupted == FALSE)
4333 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Signature is not corrupted by driver, hence not restoring\n");
4334 return STATUS_SUCCESS;
4336 if(Adapter->bAllDSDWriteAllow == FALSE)
4338 if(IsSectionWritable(Adapter,eFlashSectionVal) == FALSE)
4340 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Write signature");
4341 return SECTOR_IS_NOT_WRITABLE;
4344 if((eFlashSectionVal == DSD0) ||(eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2))
4346 uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER) ;
4347 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader ;
4349 uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber);
4351 if((ReadDSDSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
4353 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corrupted Pattern is not there. Hence won't write sig");
4354 return STATUS_FAILURE;
4358 else if((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2))
4360 uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
4361 //uiOffset = 0;
4362 uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber);
4363 if((ReadISOSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
4365 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Currupted Pattern is not there. Hence won't write sig");
4366 return STATUS_FAILURE;
4369 else
4371 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
4372 return STATUS_FAILURE;
4375 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature");
4378 Adapter->bHeaderChangeAllowed = TRUE;
4379 Adapter->bSigCorrupted = FALSE;
4380 BcmFlash2xBulkWrite(Adapter, &uiSignature,eFlashSectionVal,uiOffset,SIGNATURE_SIZE,TRUE);
4381 Adapter->bHeaderChangeAllowed = FALSE;
4385 return STATUS_SUCCESS;
4388 validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
4389 if requested Bytes goes beyond the Requested section, it reports error.
4390 @Adapater :- Bcm Driver Private Data Structure
4391 @psFlash2xReadWrite :-Flash2x Read/write structure pointer
4393 Return values:-Return TRUE is request is valid else FALSE.
4397 INT validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite)
4399 UINT uiNumOfBytes = 0 ;
4400 UINT uiSectStartOffset = 0 ;
4401 UINT uiSectEndOffset = 0;
4402 uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
4404 if(IsSectionExistInFlash(Adapter,psFlash2xReadWrite->Section) != TRUE)
4406 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%x> does not exixt in Flash",psFlash2xReadWrite->Section);
4407 return FALSE;
4409 uiSectStartOffset = BcmGetSectionValStartOffset(Adapter,psFlash2xReadWrite->Section);
4410 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n",uiSectStartOffset,psFlash2xReadWrite->Section);
4411 if((psFlash2xReadWrite->Section == ISO_IMAGE1) ||(psFlash2xReadWrite->Section == ISO_IMAGE2))
4413 if(psFlash2xReadWrite->Section == ISO_IMAGE1)
4415 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1) -
4416 BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1)+
4417 BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART2) -
4418 BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART2)+
4419 BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART3) -
4420 BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART3);
4422 else if(psFlash2xReadWrite->Section == ISO_IMAGE2)
4424 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2) -
4425 BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)+
4426 BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART2) -
4427 BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART2)+
4428 BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART3) -
4429 BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART3);
4433 //since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset
4434 //it should be added in startoffset. so that check done in last of this function can be valued.
4435 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset ;
4437 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Total size of the ISO Image :%x",uiSectEndOffset);
4439 else
4440 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,psFlash2xReadWrite->Section);
4441 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x \n",uiSectEndOffset);
4443 //Checking the boundary condition
4444 if((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
4445 return TRUE;
4446 else
4448 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid Request....");
4449 return FALSE;
4455 IsFlash2x :- check for Flash 2.x
4456 @Adapater :- Bcm Driver Private Data Structure
4458 Return value:-
4459 return TRUE if flah2.x of hgher version else return false.
4462 INT IsFlash2x(PMINI_ADAPTER Adapter)
4464 if(Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
4465 return TRUE ;
4466 else
4467 return FALSE;
4470 GetFlashBaseAddr :- Calculate the Flash Base address
4471 @Adapater :- Bcm Driver Private Data Structure
4473 Return Value:-
4474 Success :- Base Address of the Flash
4477 static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter)
4480 UINT uiBaseAddr = 0;
4482 if(Adapter->bDDRInitDone)
4485 For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
4486 In case of Raw Read... use the default value
4488 if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
4489 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
4491 uiBaseAddr = Adapter->uiFlashBaseAdd ;
4492 else
4493 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
4495 else
4498 For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
4499 In case of Raw Read... use the default value
4501 if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
4502 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
4504 uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4505 else
4506 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4509 return uiBaseAddr ;
4512 BcmCopySection :- This API is used to copy the One section in another. Both section should
4513 be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
4515 @Adapater :- Bcm Driver Private Data Structure
4516 @SrcSection :- Source section From where data has to be copied
4517 @DstSection :- Destination section to which data has to be copied
4518 @offset :- Offset from/to where data has to be copied from one section to another.
4519 @numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
4520 in case of numofBytes equal zero complete section will be copied.
4522 Return Values-
4523 Success : Return STATUS_SUCCESS
4524 Faillure :- return negative error code
4528 INT BcmCopySection(PMINI_ADAPTER Adapter,
4529 FLASH2X_SECTION_VAL SrcSection,
4530 FLASH2X_SECTION_VAL DstSection,
4531 UINT offset,
4532 UINT numOfBytes)
4534 UINT BuffSize = 0 ;
4535 UINT BytesToBeCopied = 0;
4536 PUCHAR pBuff = NULL ;
4537 INT Status = STATUS_SUCCESS ;
4538 if(SrcSection == DstSection)
4540 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source and Destination should be different ...try again");
4541 return -EINVAL;
4543 if((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2))
4545 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source should be DSD subsection");
4546 return -EINVAL;
4548 if((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2))
4550 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destination should be DSD subsection");
4551 return -EINVAL;
4554 //if offset zero means have to copy complete secton
4556 if(numOfBytes == 0)
4558 numOfBytes = BcmGetSectionValEndOffset(Adapter,SrcSection)
4559 - BcmGetSectionValStartOffset(Adapter,SrcSection);
4561 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Section Size :0x%x",numOfBytes);
4564 if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,SrcSection)
4565 - BcmGetSectionValStartOffset(Adapter,SrcSection))
4567 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
4568 offset, numOfBytes);
4569 return -EINVAL;
4572 if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,DstSection)
4573 - BcmGetSectionValStartOffset(Adapter,DstSection))
4575 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
4576 offset, numOfBytes);
4577 return -EINVAL;
4581 if(numOfBytes > Adapter->uiSectorSize )
4582 BuffSize = Adapter->uiSectorSize;
4583 else
4584 BuffSize = numOfBytes ;
4586 pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL);
4587 if(pBuff == NULL)
4589 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed.. ");
4590 return -ENOMEM;
4594 BytesToBeCopied = Adapter->uiSectorSize ;
4595 if(offset % Adapter->uiSectorSize)
4596 BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
4597 if(BytesToBeCopied > numOfBytes)
4598 BytesToBeCopied = numOfBytes ;
4602 Adapter->bHeaderChangeAllowed = TRUE;
4606 Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset,BytesToBeCopied);
4607 if(Status)
4609 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection,BytesToBeCopied);
4610 break;
4612 Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pBuff,DstSection,offset,BytesToBeCopied,FALSE);
4613 if(Status)
4615 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection,BytesToBeCopied);
4616 break;
4618 offset = offset + BytesToBeCopied;
4619 numOfBytes = numOfBytes - BytesToBeCopied ;
4620 if(numOfBytes)
4622 if(numOfBytes > Adapter->uiSectorSize )
4623 BytesToBeCopied = Adapter->uiSectorSize;
4624 else
4625 BytesToBeCopied = numOfBytes;
4627 }while(numOfBytes > 0) ;
4628 kfree(pBuff);
4629 Adapter->bHeaderChangeAllowed = FALSE ;
4630 return Status;
4634 SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
4635 @Adapater :- Bcm Driver Private Data Structure
4636 @pBuff :- Data buffer that has to be written in sector having the header map.
4637 @uiOffset :- Flash offset that has to be written.
4639 Return value :-
4640 Success :- On success return STATUS_SUCCESS
4641 Faillure :- Return negative error code
4645 INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset)
4647 UINT offsetToProtect = 0,HeaderSizeToProtect =0;
4648 BOOLEAN bHasHeader = FALSE ;
4649 PUCHAR pTempBuff =NULL;
4650 UINT uiSectAlignAddr = 0;
4651 UINT sig = 0;
4653 //making the offset sector aligned
4654 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4657 if((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD2)- Adapter->uiSectorSize)||
4658 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD1)- Adapter->uiSectorSize)||
4659 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD0)- Adapter->uiSectorSize))
4662 //offset from the sector boundary having the header map
4663 offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
4664 HeaderSizeToProtect = sizeof(DSD_HEADER);
4665 bHasHeader = TRUE ;
4668 if(uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1) ||
4669 uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2))
4671 offsetToProtect = 0;
4672 HeaderSizeToProtect = sizeof(ISO_HEADER);
4673 bHasHeader = TRUE;
4675 //If Header is present overwrite passed buffer with this
4676 if(bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE))
4678 pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL);
4679 if(pTempBuff == NULL)
4681 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed ");
4682 return -ENOMEM;
4684 //Read header
4685 BeceemFlashBulkRead(Adapter,(PUINT)pTempBuff,(uiSectAlignAddr + offsetToProtect),HeaderSizeToProtect);
4686 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pTempBuff ,HeaderSizeToProtect);
4687 //Replace Buffer content with Header
4688 memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect);
4690 kfree(pTempBuff);
4692 if(bHasHeader && Adapter->bSigCorrupted)
4694 sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)));
4695 sig = ntohl(sig);
4696 if((sig & 0xFF000000) != CORRUPTED_PATTERN)
4698 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Desired pattern is not at sig offset. Hence won't restore");
4699 Adapter->bSigCorrupted = FALSE;
4700 return STATUS_SUCCESS;
4702 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Corrupted sig is :%X", sig);
4703 *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)))= htonl(DSD_IMAGE_MAGIC_NUMBER);
4704 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature in Header Write only");
4705 Adapter->bSigCorrupted = FALSE;
4708 return STATUS_SUCCESS ;
4712 BcmDoChipSelect : This will selcet the appropriate chip for writing.
4713 @Adapater :- Bcm Driver Private Data Structure
4715 OutPut:-
4716 Select the Appropriate chip and retrn status Success
4718 static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset)
4720 UINT FlashConfig = 0;
4721 INT ChipNum = 0;
4722 UINT GPIOConfig = 0;
4723 UINT PartNum = 0;
4725 ChipNum = offset / FLASH_PART_SIZE ;
4728 // Chip Select mapping to enable flash0.
4729 // To select flash 0, we have to OR with (0<<12).
4730 // ORing 0 will have no impact so not doing that part.
4731 // In future if Chip select value changes from 0 to non zero,
4732 // That needs be taken care with backward comaptibility. No worries for now.
4736 SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
4737 if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
4738 Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
4739 power down modes (Idle mode/shutdown mode), the values in the register will be different.
4742 if(Adapter->SelectedChip == ChipNum)
4743 return STATUS_SUCCESS;
4745 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum);
4746 Adapter->SelectedChip = ChipNum ;
4748 //bit[13..12] will select the appropriate chip
4749 rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4750 rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4753 switch(ChipNum)
4755 case 0:
4756 PartNum = 0;
4757 break;
4758 case 1:
4759 PartNum = 3;
4760 GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
4761 break;
4762 case 2:
4763 PartNum = 1;
4764 GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
4765 break;
4766 case 3:
4767 PartNum = 2;
4768 GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
4769 break;
4772 /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
4773 nothing to do... can return immediately.
4774 ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
4775 Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
4776 These values are not written by host other than during CHIP_SELECT.
4778 if(PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
4779 return STATUS_SUCCESS;
4781 //clearing the bit[13..12]
4782 FlashConfig &= 0xFFFFCFFF;
4783 FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); //00
4785 wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4786 udelay(100);
4788 wrmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
4789 udelay(100);
4791 return STATUS_SUCCESS;
4794 INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
4796 UINT uiDSDsig = 0;
4797 //UINT sigoffsetInMap = 0;
4798 //DSD_HEADER dsdHeader = {0};
4801 //sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader;
4803 if(dsd != DSD0 && dsd != DSD1 && dsd != DSD2)
4805 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for DSDs");
4806 return STATUS_FAILURE;
4808 BcmFlash2xBulkRead(Adapter,
4809 &uiDSDsig,
4810 dsd,
4811 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber),
4812 SIGNATURE_SIZE);
4814 uiDSDsig = ntohl(uiDSDsig);
4815 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD SIG :%x", uiDSDsig);
4817 return uiDSDsig ;
4819 INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
4821 //UINT priOffsetInMap = 0 ;
4822 unsigned int uiDSDPri = STATUS_FAILURE;
4823 //DSD_HEADER dsdHeader = {0};
4824 //priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
4825 if(IsSectionWritable(Adapter,dsd))
4827 if(ReadDSDSignature(Adapter,dsd)== DSD_IMAGE_MAGIC_NUMBER)
4829 BcmFlash2xBulkRead(Adapter,
4830 &uiDSDPri,
4831 dsd,
4832 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader +FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
4835 uiDSDPri = ntohl(uiDSDPri);
4836 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD<%x> Priority :%x", dsd, uiDSDPri);
4840 return uiDSDPri;
4842 FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter)
4844 INT DSDHighestPri = STATUS_FAILURE;
4845 INT DsdPri= 0 ;
4846 FLASH2X_SECTION_VAL HighestPriDSD = 0 ;
4848 if(IsSectionWritable(Adapter,DSD2))
4850 DSDHighestPri = ReadDSDPriority(Adapter,DSD2);
4851 HighestPriDSD = DSD2 ;
4853 if(IsSectionWritable(Adapter,DSD1))
4855 DsdPri = ReadDSDPriority(Adapter,DSD1);
4856 if(DSDHighestPri < DsdPri)
4858 DSDHighestPri = DsdPri ;
4859 HighestPriDSD = DSD1;
4862 if(IsSectionWritable(Adapter,DSD0))
4864 DsdPri = ReadDSDPriority(Adapter,DSD0);
4865 if(DSDHighestPri < DsdPri)
4867 DSDHighestPri = DsdPri ;
4868 HighestPriDSD = DSD0;
4871 if(HighestPriDSD)
4872 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri);
4873 return HighestPriDSD ;
4876 INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
4878 UINT uiISOsig = 0;
4879 //UINT sigoffsetInMap = 0;
4880 //ISO_HEADER ISOHeader = {0};
4883 //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
4885 if(iso != ISO_IMAGE1 && iso != ISO_IMAGE2)
4887 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for ISOs");
4888 return STATUS_FAILURE;
4890 BcmFlash2xBulkRead(Adapter,
4891 &uiISOsig,
4892 iso,
4893 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber),
4894 SIGNATURE_SIZE);
4896 uiISOsig = ntohl(uiISOsig);
4897 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO SIG :%x", uiISOsig);
4899 return uiISOsig ;
4901 INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
4904 unsigned int ISOPri = STATUS_FAILURE;
4905 if(IsSectionWritable(Adapter,iso))
4907 if(ReadISOSignature(Adapter,iso)== ISO_IMAGE_MAGIC_NUMBER)
4909 BcmFlash2xBulkRead(Adapter,
4910 &ISOPri,
4911 iso,
4912 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
4915 ISOPri = ntohl(ISOPri);
4916 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO<%x> Priority :%x", iso, ISOPri);
4920 return ISOPri;
4922 FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter)
4924 INT ISOHighestPri = STATUS_FAILURE;
4925 INT ISOPri= 0 ;
4926 FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL ;
4928 if(IsSectionWritable(Adapter,ISO_IMAGE2))
4930 ISOHighestPri = ReadISOPriority(Adapter,ISO_IMAGE2);
4931 HighestPriISO = ISO_IMAGE2 ;
4933 if(IsSectionWritable(Adapter,ISO_IMAGE1))
4935 ISOPri = ReadISOPriority(Adapter,ISO_IMAGE1);
4936 if(ISOHighestPri < ISOPri)
4938 ISOHighestPri = ISOPri ;
4939 HighestPriISO = ISO_IMAGE1;
4942 if(HighestPriISO)
4943 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest ISO :%x and its Pri :%x",HighestPriISO,ISOHighestPri);
4944 return HighestPriISO ;
4946 INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
4947 PUINT pBuff,
4948 FLASH2X_SECTION_VAL eFlash2xSectionVal,
4949 UINT uiOffset,
4950 UINT uiNumBytes
4953 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
4954 UINT uiTemp = 0, value = 0 ;
4955 UINT i = 0;
4956 UINT uiPartOffset = 0;
4957 #endif
4958 UINT uiStartOffset = 0;
4959 //Adding section start address
4960 INT Status = STATUS_SUCCESS;
4961 PUCHAR pcBuff = (PUCHAR)pBuff;
4963 if(uiNumBytes % Adapter->ulFlashWriteSize)
4965 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
4966 return STATUS_FAILURE;
4969 uiStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
4971 if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
4973 return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
4976 uiOffset = uiOffset + uiStartOffset;
4978 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
4979 Status = bcmflash_raw_writenoerase((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE), pcBuff,uiNumBytes);
4980 #else
4981 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4982 value = 0;
4983 wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
4985 Adapter->SelectedChip = RESET_CHIP_SELECT;
4986 BcmDoChipSelect(Adapter,uiOffset);
4987 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
4989 for(i = 0 ; i< uiNumBytes; i += Adapter->ulFlashWriteSize)
4991 if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
4992 Status = flashByteWrite(Adapter,uiPartOffset, pcBuff);
4993 else
4994 Status = flashWrite(Adapter,uiPartOffset, pcBuff);
4996 if(Status != STATUS_SUCCESS)
4997 break;
4999 pcBuff = pcBuff + Adapter->ulFlashWriteSize;
5000 uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize;
5002 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
5003 Adapter->SelectedChip = RESET_CHIP_SELECT;
5004 #endif
5006 return Status;
5009 BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
5012 BOOLEAN SectionPresent = FALSE ;
5014 switch(section)
5017 case ISO_IMAGE1 :
5018 if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
5019 (IsNonCDLessDevice(Adapter) == FALSE))
5020 SectionPresent = TRUE ;
5021 break;
5022 case ISO_IMAGE2 :
5023 if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
5024 (IsNonCDLessDevice(Adapter) == FALSE))
5025 SectionPresent = TRUE ;
5026 break;
5027 case DSD0 :
5028 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
5029 SectionPresent = TRUE ;
5030 break;
5031 case DSD1 :
5032 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
5033 SectionPresent = TRUE ;
5034 break;
5035 case DSD2 :
5036 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
5037 SectionPresent = TRUE ;
5038 break;
5039 case VSA0 :
5040 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
5041 SectionPresent = TRUE ;
5042 break;
5043 case VSA1 :
5044 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
5045 SectionPresent = TRUE ;
5046 break;
5047 case VSA2 :
5048 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
5049 SectionPresent = TRUE ;
5050 break;
5051 case SCSI :
5052 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
5053 SectionPresent = TRUE ;
5054 break;
5055 case CONTROL_SECTION :
5056 if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
5057 SectionPresent = TRUE ;
5058 break;
5059 default :
5060 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
5061 SectionPresent = FALSE;
5063 return SectionPresent ;
5065 INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section)
5067 INT offset = STATUS_FAILURE;
5068 INT Status = FALSE;
5069 if(IsSectionExistInFlash(Adapter,Section) == FALSE)
5071 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section <%d> does not exixt", Section);
5072 return FALSE;
5074 offset = BcmGetSectionValStartOffset(Adapter,Section);
5075 if(offset == INVALID_OFFSET)
5077 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%d> does not exixt", Section);
5078 return FALSE;
5081 if(IsSectionExistInVendorInfo(Adapter,Section))
5083 return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
5086 Status = IsOffsetWritable(Adapter,offset);
5087 return Status ;
5090 static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
5093 PUCHAR pBuff = NULL;
5094 UINT sig = 0;
5095 UINT uiOffset = 0;
5096 UINT BlockStatus = 0;
5097 UINT uiSectAlignAddr = 0;
5099 Adapter->bSigCorrupted = FALSE;
5101 if(Adapter->bAllDSDWriteAllow == FALSE)
5103 if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
5105 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Corrupt signature");
5106 return SECTOR_IS_NOT_WRITABLE;
5110 pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
5111 if(pBuff == NULL)
5113 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
5114 return -ENOMEM ;
5117 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER);
5118 uiOffset -= MAX_RW_SIZE ;
5120 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset,MAX_RW_SIZE);
5123 sig = *((PUINT)(pBuff +12));
5124 sig =ntohl(sig);
5125 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
5126 //Now corrupting the sig by corrupting 4th last Byte.
5127 *(pBuff + 12) = 0;
5129 if(sig == DSD_IMAGE_MAGIC_NUMBER)
5131 Adapter->bSigCorrupted = TRUE;
5132 if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
5134 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize -1);
5135 BlockStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);
5137 WriteToFlashWithoutSectorErase(Adapter,(PUINT)(pBuff + 12),eFlash2xSectionVal,
5138 (uiOffset + 12),BYTE_WRITE_SUPPORT);
5139 if(BlockStatus)
5141 BcmRestoreBlockProtectStatus(Adapter,BlockStatus);
5142 BlockStatus = 0;
5145 else
5147 WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
5148 uiOffset ,MAX_RW_SIZE);
5151 else
5153 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
5154 kfree(pBuff);
5155 return STATUS_FAILURE;
5158 kfree(pBuff);
5159 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
5160 return STATUS_SUCCESS ;
5163 static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
5166 PUCHAR pBuff = NULL;
5167 UINT sig = 0;
5168 UINT uiOffset = 0;
5170 Adapter->bSigCorrupted = FALSE;
5172 if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
5174 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Corrupt signature");
5175 return SECTOR_IS_NOT_WRITABLE;
5178 pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
5179 if(pBuff == NULL)
5181 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allocate memorey");
5182 return -ENOMEM ;
5185 uiOffset = 0;
5187 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset, MAX_RW_SIZE);
5189 sig = *((PUINT)pBuff);
5190 sig =ntohl(sig);
5192 //corrupt signature
5193 *pBuff = 0;
5195 if(sig == ISO_IMAGE_MAGIC_NUMBER)
5197 Adapter->bSigCorrupted = TRUE;
5198 WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
5199 uiOffset ,Adapter->ulFlashWriteSize);
5201 else
5203 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
5204 kfree(pBuff);
5205 return STATUS_FAILURE;
5208 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
5209 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
5211 kfree(pBuff);
5212 return STATUS_SUCCESS ;
5215 BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter)
5217 if(Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
5218 return TRUE;
5219 else
5220 return FALSE ;