#include "headers.h"

#define DWORD unsigned int

static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset);
static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter);
static INT BcmGetActiveISO(PMINI_ADAPTER Adapter);
static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter);
static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter);
static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize);

static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter);
static INT BcmGetNvmSize(PMINI_ADAPTER Adapter);
static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter);
static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter);

static INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);

static B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset);
static INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section);
static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section);

static INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
static INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd);
static INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);
static INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso);

static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
static INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
static INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, PUINT pBuff,
					  FLASH2X_SECTION_VAL eFlash2xSectionVal,
					  UINT uiOffset, UINT uiNumBytes);
static FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter);
static FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter);

static INT BeceemFlashBulkRead(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	UINT uiOffset,
	UINT uiNumBytes);

static INT BeceemFlashBulkWrite(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	UINT uiOffset,
	UINT uiNumBytes,
	BOOLEAN bVerify);

static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter);

static INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData);

// Procedure:	ReadEEPROMStatusRegister
//
// Description: Reads the standard EEPROM Status Register.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------

static UCHAR ReadEEPROMStatusRegister( PMINI_ADAPTER Adapter )
{
	UCHAR uiData = 0;
	DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
	UINT uiStatus = 0;
	UINT value = 0;
	UINT value1 = 0;

	/* Read the EEPROM status register */
	value = EEPROM_READ_STATUS_REGISTER ;
	wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));

	while ( dwRetries != 0 )
	{
		value=0;
		uiStatus = 0 ;
		rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus));
		if(Adapter->device_removed == TRUE)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got removed hence exiting....");
			break;
		}

		/* Wait for Avail bit to be set. */
		if ( ( uiStatus & EEPROM_READ_DATA_AVAIL) != 0 )
		{
			/* Clear the Avail/Full bits - which ever is set. */
			value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
			wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));

			value =0;
			rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
			uiData = (UCHAR)value;

			break;
		}

		dwRetries-- ;
		if ( dwRetries == 0 )
		{
			 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
			 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
			 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);
			return uiData;
		}
		if( !(dwRetries%RETRIES_PER_DELAY) )
			msleep(1);
		uiStatus = 0 ;
	}
	return uiData;
} /* ReadEEPROMStatusRegister */

//-----------------------------------------------------------------------------
// Procedure:	ReadBeceemEEPROMBulk
//
// Description: This routine reads 16Byte data from EEPROM
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//      dwAddress   - EEPROM Offset to read the data from.
//      pdwData     - Pointer to double word where data needs to be stored in.  //		dwNumWords  - Number of words.  Valid values are 4 ONLY.
//
// Returns:
//		OSAL_STATUS_CODE:
//-----------------------------------------------------------------------------

INT ReadBeceemEEPROMBulk( PMINI_ADAPTER Adapter,
									   DWORD dwAddress,
									   DWORD *pdwData,
									   DWORD dwNumWords
									 )
{
	DWORD dwIndex = 0;
	DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
	UINT uiStatus  = 0;
	UINT value= 0;
	UINT value1 = 0;
	UCHAR *pvalue;

	/* Flush the read and cmd queue. */
	value=( EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH );
	wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
	value=0;
	wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));

	/* Clear the Avail/Full bits. */
	value=( EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL );
	wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));

	value= dwAddress | ( (dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ );
	wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));

	while ( dwRetries != 0 )
		{

		uiStatus = 0;
		rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
		if(Adapter->device_removed == TRUE)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got Removed.hence exiting from loop...");
			return -ENODEV;
		}

		/* If we are reading 16 bytes we want to be sure that the queue
		 * is full before we read.  In the other cases we are ok if the
		 * queue has data available */
		if ( dwNumWords == 4 )
		{
			if ( ( uiStatus & EEPROM_READ_DATA_FULL ) != 0 )
			{
				/* Clear the Avail/Full bits - which ever is set. */
				value = ( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) ) ;
				wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
				break;
			}
		}
		else if ( dwNumWords == 1 )
		{

			if ( ( uiStatus & EEPROM_READ_DATA_AVAIL ) != 0 )
			{
				/* We just got Avail and we have to read 32bits so we
				 * need this sleep for Cardbus kind of devices. */
				if (Adapter->chip_id == 0xBECE0210 )
	  					udelay(800);

				/* Clear the Avail/Full bits - which ever is set. */
				value=( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) );
				wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
				break;
			}
		}

		uiStatus = 0;

		dwRetries--;
		if(dwRetries == 0)
		{
			value=0;
			value1=0;
			rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
			rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
			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);
			return STATUS_FAILURE;
		}
		if( !(dwRetries%RETRIES_PER_DELAY) )
			msleep(1);
	}

	for ( dwIndex = 0; dwIndex < dwNumWords ; dwIndex++ )
	{
		/* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */
		pvalue = (PUCHAR)(pdwData + dwIndex);

		value =0;
		rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));

		pvalue[0] = value;

		value = 0;
		rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));

		pvalue[1] = value;

		value =0;
		rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));

		pvalue[2] = value;

		value = 0;
		rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));

		pvalue[3] = value;
	}

	return STATUS_SUCCESS;
} /* ReadBeceemEEPROMBulk() */

//-----------------------------------------------------------------------------
// Procedure:	ReadBeceemEEPROM
//
// Description: This routine reads 4 data from EEPROM.  It uses 1 or 2 page
//				reads to do this operation.
//
// Arguments:
//		Adapter     - ptr to Adapter object instance
//      uiOffset	- EEPROM Offset to read the data from.
//      pBuffer		- Pointer to word where data needs to be stored in.
//
// Returns:
//		OSAL_STATUS_CODE:
//-----------------------------------------------------------------------------

INT ReadBeceemEEPROM( PMINI_ADAPTER Adapter,
								   DWORD uiOffset,
								   DWORD *pBuffer
								 )
{
	UINT uiData[8]	 	= {0};
	UINT uiByteOffset	= 0;
	UINT uiTempOffset	= 0;

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," ====> ");

	uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
	uiByteOffset = uiOffset - uiTempOffset;

	ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);

	/* A word can overlap at most over 2 pages. In that case we read the
	 * next page too. */
	if ( uiByteOffset > 12 )
	{
		ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
	}

	memcpy( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4);

	return STATUS_SUCCESS;
} /* ReadBeceemEEPROM() */



INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter)
{
	INT Status;
	unsigned char puMacAddr[6];

	Status = BeceemNVMRead(Adapter,
			(PUINT)&puMacAddr[0],
			INIT_PARAMS_1_MACADDRESS_ADDRESS,
			MAC_ADDRESS_SIZE);

	if(Status == STATUS_SUCCESS)
		memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);

	return Status;
}

//-----------------------------------------------------------------------------
// Procedure:	BeceemEEPROMBulkRead
//
// Description: Reads the EEPROM and returns the Data.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		pBuffer    - Buffer to store the data read from EEPROM
//		uiOffset   - Offset of EEPROM from where data should be read
//		uiNumBytes - Number of bytes to be read from the EEPROM.
//
// Returns:
//		OSAL_STATUS_SUCCESS - if EEPROM read is successfull.
//		<FAILURE>			- if failed.
//-----------------------------------------------------------------------------

INT BeceemEEPROMBulkRead(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	UINT uiOffset,
	UINT uiNumBytes)
{
	UINT uiData[4]		  = {0};
	//UINT uiAddress 		  = 0;
	UINT uiBytesRemaining = uiNumBytes;
	UINT uiIndex 		  = 0;
	UINT uiTempOffset  	  = 0;
	UINT uiExtraBytes     = 0;
	UINT uiFailureRetries = 0;
	PUCHAR pcBuff = (PUCHAR)pBuffer;


	if(uiOffset%MAX_RW_SIZE&& uiBytesRemaining)
	{
		uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
		uiExtraBytes = uiOffset-uiTempOffset;
		ReadBeceemEEPROMBulk(Adapter,uiTempOffset,(PUINT)&uiData[0],4);
		if(uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes))
		{
			memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes);

			uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes);
			uiIndex += (MAX_RW_SIZE - uiExtraBytes);
			uiOffset += (MAX_RW_SIZE - uiExtraBytes);
		}
		else
		{
			memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining);
			uiIndex += uiBytesRemaining;
			uiOffset += uiBytesRemaining;
			uiBytesRemaining = 0;
		}


	}


	while(uiBytesRemaining && uiFailureRetries != 128)
	{
		if(Adapter->device_removed )
		{
			return -1;
		}

		if(uiBytesRemaining >= MAX_RW_SIZE)
		{
			/* For the requests more than or equal to 16 bytes, use bulk
			 * read function to make the access faster.
			 * We read 4 Dwords of data */
			if(0 == ReadBeceemEEPROMBulk(Adapter,uiOffset,&uiData[0],4))
			{
				memcpy(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE);
				uiOffset += MAX_RW_SIZE;
				uiBytesRemaining -= MAX_RW_SIZE;
				uiIndex += MAX_RW_SIZE;
			}
			else
			{
				uiFailureRetries++;
				mdelay(3);//sleep for a while before retry...
			}
		}
		else if(uiBytesRemaining >= 4)
		{
			if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
			{
				memcpy(pcBuff+uiIndex,&uiData[0],4);
				uiOffset += 4;
				uiBytesRemaining -= 4;
				uiIndex +=4;
			}
			else
			{
				uiFailureRetries++;
				mdelay(3);//sleep for a while before retry...
			}
		}
		else
		{ // Handle the reads less than 4 bytes...
			PUCHAR pCharBuff = (PUCHAR)pBuffer;
			pCharBuff += uiIndex;
			if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
			{
				memcpy(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested.
				uiBytesRemaining = 0;
			}
			else
			{
				uiFailureRetries++;
				mdelay(3);//sleep for a while before retry...
			}
		}

	}

	return 0;
}

//-----------------------------------------------------------------------------
// Procedure:	BeceemFlashBulkRead
//
// Description: Reads the FLASH and returns the Data.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		pBuffer    - Buffer to store the data read from FLASH
//		uiOffset   - Offset of FLASH from where data should be read
//		uiNumBytes - Number of bytes to be read from the FLASH.
//
// Returns:
//		OSAL_STATUS_SUCCESS - if FLASH read is successfull.
//		<FAILURE>			- if failed.
//-----------------------------------------------------------------------------

static INT BeceemFlashBulkRead(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	UINT uiOffset,
	UINT uiNumBytes)
{
	UINT uiIndex = 0;
	UINT uiBytesToRead = uiNumBytes;
	INT Status = 0;
	UINT uiPartOffset = 0;

	if(Adapter->device_removed )
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device Got Removed ");
		return -ENODEV;
	}

	//Adding flash Base address
//	uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
  Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
  return Status;
#endif

	Adapter->SelectedChip = RESET_CHIP_SELECT;

	if(uiOffset % MAX_RW_SIZE)
	{
		BcmDoChipSelect(Adapter,uiOffset);
		uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);

		uiBytesToRead = MAX_RW_SIZE - (uiOffset%MAX_RW_SIZE);
		uiBytesToRead = MIN(uiNumBytes,uiBytesToRead);

		if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
		{
			Status = -1;
			Adapter->SelectedChip = RESET_CHIP_SELECT;
			return Status;
		}

		uiIndex += uiBytesToRead;
		uiOffset += uiBytesToRead;
		uiNumBytes -= uiBytesToRead;
	}

	while(uiNumBytes)
	{
		BcmDoChipSelect(Adapter,uiOffset);
		uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);

		uiBytesToRead = MIN(uiNumBytes,MAX_RW_SIZE);

		if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
		{
			Status = -1;
			break;
		}


		uiIndex += uiBytesToRead;
		uiOffset += uiBytesToRead;
		uiNumBytes -= uiBytesToRead;

	}
	Adapter->SelectedChip = RESET_CHIP_SELECT;
	return Status;
}

//-----------------------------------------------------------------------------
// Procedure:	BcmGetFlashSize
//
// Description: Finds the size of FLASH.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//
// Returns:
//		UINT - size of the FLASH Storage.
//
//-----------------------------------------------------------------------------

static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter)
{
	if(IsFlash2x(Adapter))
		return 	(Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER));
	else
		return 32*1024;


}

//-----------------------------------------------------------------------------
// Procedure:	BcmGetEEPROMSize
//
// Description: Finds the size of EEPROM.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//
// Returns:
//		UINT - size of the EEPROM Storage.
//
//-----------------------------------------------------------------------------

static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter)
{
	UINT uiData = 0;
	UINT uiIndex = 0;

//
// if EEPROM is present and already Calibrated,it will have
// 'BECM' string at 0th offset.
//	To find the EEPROM size read the possible boundaries of the
// EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will
// result in wrap around. So when we get the End of the EEPROM we will
// get 'BECM' string which is indeed at offset 0.
//
	BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
	if(uiData == BECM)
	{
		for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
		{
			BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
			if(uiData == BECM)
			{
				return uiIndex*1024;
			}
		}
	}
	else
	{
//
// EEPROM may not be present or not programmed
//

        uiData = 0xBABEFACE;
		if(0 == BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&uiData,0,4,TRUE))
		{
			uiData = 0;
			for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
			{
				BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
				if(uiData == 0xBABEFACE)
				{
					return uiIndex*1024;
				}
			}
		}

	}
	return 0;
}


//-----------------------------------------------------------------------------
// Procedure:	FlashSectorErase
//
// Description: Finds the sector size of the FLASH.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		addr	   - sector start address
//		numOfSectors - number of sectors to  be erased.
//
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------


static INT FlashSectorErase(PMINI_ADAPTER Adapter,
	UINT addr,
	UINT numOfSectors)
{
	UINT iIndex = 0, iRetries = 0;
	UINT uiStatus = 0;
	UINT value;

	for(iIndex=0;iIndex<numOfSectors;iIndex++)
	{
		value = 0x06000000;
		wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));

		value = (0xd8000000 | (addr & 0xFFFFFF));
		wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
		iRetries = 0;

		do
		{
			value = (FLASH_CMD_STATUS_REG_READ << 24);
			if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
				return STATUS_FAILURE;
			}

			if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
				return STATUS_FAILURE;
			}
			iRetries++;
			//After every try lets make the CPU free for 10 ms. generally time taken by the
			//the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms
			//won't hamper performance in any case.
			msleep(10);
		}while((uiStatus & 0x1) && (iRetries < 400));

		if(uiStatus & 0x1)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"iRetries crossing the limit of 80000\n");
			return STATUS_FAILURE;
		}

		addr += Adapter->uiSectorSize;
	}
	return 0;
}
//-----------------------------------------------------------------------------
// Procedure:	flashByteWrite
//
// Description: Performs Byte by Byte write to flash
//
// Arguments:
//		Adapter   - ptr to Adapter object instance
//		uiOffset   - Offset of the flash where data needs to be written to.
//		pData	- Address of Data to be written.
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------

static INT flashByteWrite(
	PMINI_ADAPTER Adapter,
	UINT uiOffset,
	PVOID pData)
{

	UINT uiStatus = 0;
	INT  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3

	UINT value;
	ULONG ulData = *(PUCHAR)pData;

//
// need not write 0xFF because write requires an erase and erase will
// make whole sector 0xFF.
//

	if(0xFF == ulData)
	{
		return STATUS_SUCCESS;
	}

//	DumpDebug(NVM_RW,("flashWrite ====>\n"));
	value = (FLASH_CMD_WRITE_ENABLE << 24);
	if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
		return STATUS_FAILURE;
	}
	if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0 )
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
		return STATUS_FAILURE;
	}
	value = (0x02000000 | (uiOffset & 0xFFFFFF));
	if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
		return STATUS_FAILURE;
	}

	//__udelay(950);

	do
	{
		value = (FLASH_CMD_STATUS_REG_READ << 24);
	  	if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
	  	{
	  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
			return STATUS_FAILURE;
	  	}
	  	//__udelay(1);
	  	if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
	  	{
	  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
			return STATUS_FAILURE;
		}
	  	iRetries--;
		if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
			 msleep(1);

	}while((uiStatus & 0x1) && (iRetries  >0) );

	if(uiStatus & 0x1)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
		return STATUS_FAILURE ;
	}

	return STATUS_SUCCESS;
}



//-----------------------------------------------------------------------------
// Procedure:	flashWrite
//
// Description: Performs write to flash
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		uiOffset   - Offset of the flash where data needs to be written to.
//		pData	- Address of Data to be written.
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------

static INT flashWrite(
	PMINI_ADAPTER Adapter,
	UINT uiOffset,
	PVOID pData)

{
	//UINT uiStatus = 0;
	//INT  iRetries = 0;
	//UINT uiReadBack = 0;

	UINT uiStatus = 0;
	INT  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3

	UINT value;
	UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
//
// need not write 0xFFFFFFFF because write requires an erase and erase will
// make whole sector 0xFFFFFFFF.
//
	if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
	{
		return 0;
	}

	value = (FLASH_CMD_WRITE_ENABLE << 24);

	if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
		return STATUS_FAILURE;
	}
	if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
		return STATUS_FAILURE;
	}

	//__udelay(950);
	do
	{
		value = (FLASH_CMD_STATUS_REG_READ << 24);
	  	if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
	  	{
	  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
			return STATUS_FAILURE;
	  	}
	  	//__udelay(1);
	  	if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
	  	{
	  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
			return STATUS_FAILURE;
		}

		iRetries--;
		//this will ensure that in there will be no changes in the current path.
		//currently one rdm/wrm takes 125 us.
		//Hence  125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay)
		//Hence current implementation cycle will intoduce no delay in current path
		if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
				msleep(1);
	}while((uiStatus & 0x1) && (iRetries > 0));

	if(uiStatus & 0x1)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
		return STATUS_FAILURE ;
	}

	return STATUS_SUCCESS;
}

//-----------------------------------------------------------------------------
// Procedure:	flashByteWriteStatus
//
// Description: Performs byte by byte write to flash with write done status check
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		uiOffset    - Offset of the flash where data needs to be written to.
//		pData	 - Address of the Data to be written.
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------
static INT flashByteWriteStatus(
	PMINI_ADAPTER Adapter,
	UINT uiOffset,
	PVOID pData)
{
	UINT uiStatus = 0;
	INT  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
	ULONG ulData  = *(PUCHAR)pData;
	UINT value;

//
// need not write 0xFFFFFFFF because write requires an erase and erase will
// make whole sector 0xFFFFFFFF.
//

	if(0xFF == ulData)
	{
		return STATUS_SUCCESS;
	}

	//	DumpDebug(NVM_RW,("flashWrite ====>\n"));

	value = (FLASH_CMD_WRITE_ENABLE << 24);
	if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
		return STATUS_SUCCESS;
	}
	if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
		return STATUS_FAILURE;
	}
	value = (0x02000000 | (uiOffset & 0xFFFFFF));
	if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
		return STATUS_FAILURE;
	}

    //msleep(1);

	do
	{
		value = (FLASH_CMD_STATUS_REG_READ << 24);
		if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
			return STATUS_FAILURE;
		}
		//__udelay(1);
		if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
			return STATUS_FAILURE;
		}

		iRetries--;
		if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
				msleep(1);
	}while((uiStatus & 0x1) && (iRetries > 0));

	if(uiStatus & 0x1)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
		return STATUS_FAILURE ;
	}

	return STATUS_SUCCESS;

}
//-----------------------------------------------------------------------------
// Procedure:	flashWriteStatus
//
// Description: Performs write to flash with write done status check
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		uiOffset    - Offset of the flash where data needs to be written to.
//		pData	 - Address of the Data to be written.
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------

static INT flashWriteStatus(
	PMINI_ADAPTER Adapter,
	UINT uiOffset,
	PVOID pData)
{
	UINT uiStatus = 0;
	INT  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
	//UINT uiReadBack = 0;
	UINT value;
	UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};

//
// need not write 0xFFFFFFFF because write requires an erase and erase will
// make whole sector 0xFFFFFFFF.
//
	if (!memcmp(pData,uiErasePattern,MAX_RW_SIZE))
	{
		return 0;
	}

	value = (FLASH_CMD_WRITE_ENABLE << 24);
	if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
		return STATUS_FAILURE;
	}
	if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
		return STATUS_FAILURE;
	}
   // __udelay(1);

	do
	{
		value = (FLASH_CMD_STATUS_REG_READ << 24);
	  	if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
	  	{
	  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
			return STATUS_FAILURE;
	  	}
	  	//__udelay(1);
	  	if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
	  	{
	  		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
			return STATUS_FAILURE;
		}
	  	iRetries--;
		//this will ensure that in there will be no changes in the current path.
		//currently one rdm/wrm takes 125 us.
		//Hence  125 *2  * FLASH_PER_RETRIES_DELAY  >3 ms(worst case delay)
		//Hence current implementation cycle will intoduce no delay in current path
		if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
				msleep(1);
	}while((uiStatus & 0x1) && (iRetries >0));

	if(uiStatus & 0x1)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
		return STATUS_FAILURE ;
	}

	return STATUS_SUCCESS;
}

//-----------------------------------------------------------------------------
// Procedure:	BcmRestoreBlockProtectStatus
//
// Description: Restores the original block protection status.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		ulWriteStatus   -Original status
// Returns:
//		<VOID>
//
//-----------------------------------------------------------------------------

static VOID BcmRestoreBlockProtectStatus(PMINI_ADAPTER Adapter,ULONG ulWriteStatus)
{
	UINT value;
	value = (FLASH_CMD_WRITE_ENABLE<< 24);
	wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));

	udelay(20);
	value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
	wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
	udelay(20);
}
//-----------------------------------------------------------------------------
// Procedure:	BcmFlashUnProtectBlock
//
// Description: UnProtects appropriate blocks for writing.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		uiOffset   - Offset of the flash where data needs to be written to. This should be Sector aligned.
// Returns:
//		ULONG   - Status value before UnProtect.
//
//-----------------------------------------------------------------------------
static ULONG BcmFlashUnProtectBlock(PMINI_ADAPTER Adapter,UINT uiOffset, UINT uiLength)
{
	ULONG ulStatus      = 0;
	ULONG ulWriteStatus = 0;
	UINT value;
	uiOffset = uiOffset&0x000FFFFF;

//
// Implemented only for 1MB Flash parts.
//
	if(FLASH_PART_SST25VF080B == Adapter->ulFlashID)
	{
	//
	// Get Current BP status.
	//
		value = (FLASH_CMD_STATUS_REG_READ << 24);
		wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
		udelay(10);
	//
	// Read status will be WWXXYYZZ. We have to take only WW.
	//
		rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
		ulStatus >>= 24;
		ulWriteStatus = ulStatus;

	//
	// Bits [5-2] give current block level protection status.
	// Bit5: BP3 - DONT CARE
	// BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4
	//                4 - UPPER 1/2. 5 to 7 - ALL BLOCKS
	//

		if(ulStatus)
		{
			if((uiOffset+uiLength) <= 0x80000)
			{
			//
			// Offset comes in lower half of 1MB. Protect the upper half.
			// Clear BP1 and BP0 and set BP2.
			//
				ulWriteStatus |= (0x4<<2);
				ulWriteStatus &= ~(0x3<<2);
			}
			else if((uiOffset+uiLength) <= 0xC0000)
			{
			//
			// Offset comes below Upper 1/4. Upper 1/4 can be protected.
			//  Clear BP2 and set BP1 and BP0.
			//
				ulWriteStatus |= (0x3<<2);
				ulWriteStatus &= ~(0x1<<4);
			}
			else if((uiOffset+uiLength) <= 0xE0000)
		    {
		    //
		    // Offset comes below Upper 1/8. Upper 1/8 can be protected.
		    // Clear BP2 and BP0  and set BP1
		    //
		    	ulWriteStatus |= (0x1<<3);
		    	ulWriteStatus &= ~(0x5<<2);

		    }
		    else if((uiOffset+uiLength) <= 0xF0000)
		    {
		    //
		    // Offset comes below Upper 1/16. Only upper 1/16 can be protected.
		    // Set BP0 and Clear BP2,BP1.
		    //
		    	ulWriteStatus |= (0x1<<2);
		    	ulWriteStatus &= ~(0x3<<3);
		    }
		    else
		    {
		    //
		    // Unblock all.
		    // Clear BP2,BP1 and BP0.
		    //
		    	ulWriteStatus &= ~(0x7<<2);
		    }

			value = (FLASH_CMD_WRITE_ENABLE<< 24);
			wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
			udelay(20);
			value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
			wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
			udelay(20);

		}

	}
	return ulStatus;
}
//-----------------------------------------------------------------------------
// Procedure:	BeceemFlashBulkWrite
//
// Description: Performs write to the flash
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		pBuffer 	- Data to be written.
//		uiOffset   - Offset of the flash where data needs to be written to.
//		uiNumBytes - Number of bytes to be written.
//		bVerify    - read verify flag.
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------

static INT BeceemFlashBulkWrite(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	UINT uiOffset,
	UINT uiNumBytes,
	BOOLEAN bVerify)
{
	PCHAR  pTempBuff 			= NULL;
	PUCHAR pcBuffer             = (PUCHAR)pBuffer;
	UINT  uiIndex				= 0;
	UINT  uiOffsetFromSectStart = 0;
	UINT  uiSectAlignAddr		= 0;
	UINT  uiCurrSectOffsetAddr	= 0;
	UINT  uiSectBoundary		= 0;
	UINT  uiNumSectTobeRead 	= 0;
	UCHAR ucReadBk[16]       	= {0};
	ULONG ulStatus              = 0;
	INT Status 					= STATUS_SUCCESS;
	UINT uiTemp 				= 0;
	UINT index 					= 0;
	UINT uiPartOffset 			= 0;

#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
  Status = bcmflash_raw_write((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
  return Status;
#endif

	uiOffsetFromSectStart 	= uiOffset & ~(Adapter->uiSectorSize - 1);

	//Adding flash Base address
//	uiOffset = uiOffset + GetFlashBaseAddr(Adapter);

	uiSectAlignAddr   		= uiOffset & ~(Adapter->uiSectorSize - 1);
	uiCurrSectOffsetAddr	= uiOffset & (Adapter->uiSectorSize - 1);
	uiSectBoundary	  		= uiSectAlignAddr + Adapter->uiSectorSize;

	pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
	if(NULL == pTempBuff)
		goto BeceemFlashBulkWrite_EXIT;
//
// check if the data to be written is overlapped accross sectors
//
	if(uiOffset+uiNumBytes < uiSectBoundary)
	{
		uiNumSectTobeRead = 1;
	}
	else
	{
		//      Number of sectors  = Last sector start address/First sector start address
		uiNumSectTobeRead =  (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
		if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
		{
			uiNumSectTobeRead++;
		}
	}
	//Check whether Requested sector is writable or not in case of flash2x write. But if  write call is
	// for DSD calibration, allow it without checking of sector permission

	if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE))
	{
		index = 0;
		uiTemp = uiNumSectTobeRead ;
		while(uiTemp)
		{
			 if(IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE)
			 {
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%X> is not writable",
											(uiOffsetFromSectStart + index * Adapter->uiSectorSize));
				Status = SECTOR_IS_NOT_WRITABLE;
				goto BeceemFlashBulkWrite_EXIT;
			 }
			 uiTemp = uiTemp - 1;
			 index = index + 1 ;
		}
	}
	Adapter->SelectedChip = RESET_CHIP_SELECT;
	while(uiNumSectTobeRead)
	{
		//do_gettimeofday(&tv1);
		//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));
		uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);

		BcmDoChipSelect(Adapter,uiSectAlignAddr);

		if(0 != BeceemFlashBulkRead(Adapter,
						(PUINT)pTempBuff,
						uiOffsetFromSectStart,
						Adapter->uiSectorSize))
		{
			Status = -1;
			goto BeceemFlashBulkWrite_EXIT;
		}

		//do_gettimeofday(&tr);
		//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));

		ulStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);


		if(uiNumSectTobeRead > 1)
		{

			memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
			pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
			uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
		}
		else
		{
				memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
		}

		if(IsFlash2x(Adapter))
		{
			SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart);
		}

		FlashSectorErase(Adapter,uiPartOffset,1);
		//do_gettimeofday(&te);
		//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));

		for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize)
		{
			if(Adapter->device_removed)
			{
				Status = -1;
				goto BeceemFlashBulkWrite_EXIT;
			}
			if(STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter,uiPartOffset+uiIndex,(&pTempBuff[uiIndex])))
			{
				Status = -1;
				goto BeceemFlashBulkWrite_EXIT;
			}
		}

		//do_gettimeofday(&tw);
		//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));
		for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
		{
			if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
			{
				if(Adapter->ulFlashWriteSize == 1)
				{
					UINT uiReadIndex = 0;
					for(uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++)
					{
						if(ucReadBk[uiReadIndex] != pTempBuff[uiIndex+uiReadIndex])
						{
							if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex+uiReadIndex,&pTempBuff[uiIndex+uiReadIndex]))
							{
								Status = STATUS_FAILURE;
								goto BeceemFlashBulkWrite_EXIT;
							}
						}
					}
				}
				else
				{
					if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
					{
						if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex]))
						{
							Status = STATUS_FAILURE;
							goto BeceemFlashBulkWrite_EXIT;
						}
					}
				}
			}
		}
		//do_gettimeofday(&twv);
		//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));


		if(ulStatus)
		{
			BcmRestoreBlockProtectStatus(Adapter,ulStatus);
			ulStatus = 0;
		}

		uiCurrSectOffsetAddr = 0;
		uiSectAlignAddr = uiSectBoundary;
		uiSectBoundary += Adapter->uiSectorSize;
		uiOffsetFromSectStart += Adapter->uiSectorSize;
		uiNumSectTobeRead--;
	}
	//do_gettimeofday(&tv2);
	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000));
	//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));
//
// Cleanup.
//
BeceemFlashBulkWrite_EXIT:
	if(ulStatus)
	{
		BcmRestoreBlockProtectStatus(Adapter,ulStatus);
	}
	
	kfree(pTempBuff);

	Adapter->SelectedChip = RESET_CHIP_SELECT;
	return Status;
}


//-----------------------------------------------------------------------------
// Procedure:	BeceemFlashBulkWriteStatus
//
// Description: Writes to Flash. Checks the SPI status after each write.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//		pBuffer 	- Data to be written.
//		uiOffset   - Offset of the flash where data needs to be written to.
//		uiNumBytes - Number of bytes to be written.
//		bVerify    - read verify flag.
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------

static INT BeceemFlashBulkWriteStatus(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	UINT uiOffset,
	UINT uiNumBytes,
	BOOLEAN bVerify)
{
	PCHAR  pTempBuff 			= NULL;
	PUCHAR pcBuffer             = (PUCHAR)pBuffer;
	UINT  uiIndex				= 0;
	UINT  uiOffsetFromSectStart = 0;
	UINT  uiSectAlignAddr		= 0;
	UINT  uiCurrSectOffsetAddr	= 0;
	UINT  uiSectBoundary		= 0;
	UINT  uiNumSectTobeRead 	= 0;
	UCHAR ucReadBk[16]			= {0};
	ULONG ulStatus              = 0;
	UINT  Status				= STATUS_SUCCESS;
	UINT uiTemp 				= 0;
	UINT index 					= 0;
	UINT uiPartOffset			= 0;

	uiOffsetFromSectStart 	= uiOffset & ~(Adapter->uiSectorSize - 1);

	//uiOffset += Adapter->ulFlashCalStart;
	//Adding flash Base address
//	uiOffset = uiOffset + GetFlashBaseAddr(Adapter);

	uiSectAlignAddr 		= uiOffset & ~(Adapter->uiSectorSize - 1);
	uiCurrSectOffsetAddr	= uiOffset & (Adapter->uiSectorSize - 1);
	uiSectBoundary			= uiSectAlignAddr + Adapter->uiSectorSize;

	pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
	if(NULL == pTempBuff)
		goto BeceemFlashBulkWriteStatus_EXIT;

//
// check if the data to be written is overlapped accross sectors
//
	if(uiOffset+uiNumBytes < uiSectBoundary)
	{
		uiNumSectTobeRead = 1;
	}
	else
	{
//      Number of sectors  = Last sector start address/First sector start address
		uiNumSectTobeRead =  (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
		if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
		{
			uiNumSectTobeRead++;
		}
	}

	if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE))
	{
		index = 0;
		uiTemp = uiNumSectTobeRead ;
		while(uiTemp)
		{
			 if(IsOffsetWritable(Adapter,uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE)
			 {
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%x> is not writable",
											(uiOffsetFromSectStart + index * Adapter->uiSectorSize));
				Status = SECTOR_IS_NOT_WRITABLE;
				goto BeceemFlashBulkWriteStatus_EXIT;
			 }
			 uiTemp = uiTemp - 1;
			 index = index + 1 ;
		}
	}

	Adapter->SelectedChip = RESET_CHIP_SELECT;
	while(uiNumSectTobeRead)
	{
		uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);

		BcmDoChipSelect(Adapter,uiSectAlignAddr);
		if(0 != BeceemFlashBulkRead(Adapter,
						(PUINT)pTempBuff,
						uiOffsetFromSectStart,
						Adapter->uiSectorSize))
		{
			Status = -1;
			goto BeceemFlashBulkWriteStatus_EXIT;
		}

		ulStatus = BcmFlashUnProtectBlock(Adapter,uiOffsetFromSectStart,Adapter->uiSectorSize);

		if(uiNumSectTobeRead > 1)
		{

			memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
			pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
			uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
		}
		else
		{
			memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
		}

		if(IsFlash2x(Adapter))
		{
			SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart);
		}

		FlashSectorErase(Adapter,uiPartOffset,1);

		for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize)

		{
			if(Adapter->device_removed)
			{
				Status = -1;
				goto BeceemFlashBulkWriteStatus_EXIT;
			}

			if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex]))
			{
				Status = -1;
				goto BeceemFlashBulkWriteStatus_EXIT;
			}
		}

		if(bVerify)
		{
			for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
			{

				if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
				{
					if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE))
					{
						Status = STATUS_FAILURE;
						goto BeceemFlashBulkWriteStatus_EXIT;
					}

				}

			}
		}

		if(ulStatus)
		{
			BcmRestoreBlockProtectStatus(Adapter,ulStatus);
			ulStatus = 0;
		}

		uiCurrSectOffsetAddr = 0;
		uiSectAlignAddr = uiSectBoundary;
		uiSectBoundary += Adapter->uiSectorSize;
		uiOffsetFromSectStart += Adapter->uiSectorSize;
		uiNumSectTobeRead--;
	}
//
// Cleanup.
//
BeceemFlashBulkWriteStatus_EXIT:
	if(ulStatus)
	{
		BcmRestoreBlockProtectStatus(Adapter,ulStatus);
	}

	kfree(pTempBuff);
	Adapter->SelectedChip = RESET_CHIP_SELECT;
	return Status;

}

//-----------------------------------------------------------------------------
// Procedure:	PropagateCalParamsFromEEPROMToMemory
//
// Description: Dumps the calibration section of EEPROM to DDR.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------


INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter)
{
	PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL);
	UINT uiEepromSize = 0;
	UINT uiIndex = 0;
	UINT uiBytesToCopy = 0;
	UINT uiCalStartAddr = EEPROM_CALPARAM_START;
	UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
	UINT value;
	INT Status = 0;
	if(pBuff == NULL)
	{
		return -1;
	}

	if(0 != BeceemEEPROMBulkRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET,4))
	{

		kfree(pBuff);
		return -1;
	}

	uiEepromSize >>= 16;
	if(uiEepromSize > 1024*1024)
	{
		kfree(pBuff);
		return -1;
	}


	uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);

	while(uiBytesToCopy)
	{
		if(0 != BeceemEEPROMBulkRead(Adapter,(PUINT)pBuff,uiCalStartAddr,uiBytesToCopy))
		{
			Status = -1;
			break;
		}
		wrm(Adapter,uiMemoryLoc,(PCHAR)(((PULONG)pBuff)+uiIndex),uiBytesToCopy);
		uiMemoryLoc += uiBytesToCopy;
		uiEepromSize -= uiBytesToCopy;
		uiCalStartAddr += uiBytesToCopy;
		uiIndex += uiBytesToCopy/4;
		uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);

	}
	value = 0xbeadbead;
	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-4,&value, sizeof(value));
	value = 0xbeadbead;
	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-8,&value, sizeof(value));
	kfree(pBuff);

	return Status;

}

//-----------------------------------------------------------------------------
// Procedure:	PropagateCalParamsFromFlashToMemory
//
// Description: Dumps the calibration section of EEPROM to DDR.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------

INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter)
{
	PCHAR pBuff, pPtr;
	UINT uiEepromSize = 0;
	UINT uiBytesToCopy = 0;
	//UINT uiIndex = 0;
	UINT uiCalStartAddr = EEPROM_CALPARAM_START;
	UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
	UINT value;
	INT Status = 0;
//
// Write the signature first. This will ensure firmware does not access EEPROM.
//
	value = 0xbeadbead;
	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
	value = 0xbeadbead;
	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));

	if(0 != BeceemNVMRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET, 4))
	{
		return -1;
	}
	uiEepromSize = ntohl(uiEepromSize);
	uiEepromSize >>= 16;

//
//	subtract the auto init section size
//
	uiEepromSize -= EEPROM_CALPARAM_START;

	if(uiEepromSize > 1024*1024)
	{
		return -1;
	}

	pBuff = kmalloc(uiEepromSize, GFP_KERNEL);
	if ( pBuff == NULL )
		return -1;

	if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize))
	{
		kfree(pBuff);
		return -1;
	}

	pPtr = pBuff;

	uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);

	while(uiBytesToCopy)
	{
		Status = wrm(Adapter,uiMemoryLoc,(PCHAR)pPtr,uiBytesToCopy);
		if(Status)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrm failed with status :%d",Status);
			break;
		}

		pPtr += uiBytesToCopy;
		uiEepromSize -= uiBytesToCopy;
		uiMemoryLoc += uiBytesToCopy;
		uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize);
	}

	kfree(pBuff);
	return Status;

}

//-----------------------------------------------------------------------------
// Procedure:	BeceemEEPROMReadBackandVerify
//
// Description: Read back the data written and verifies.
//
// Arguments:
//		Adapter       - ptr to Adapter object instance
//		pBuffer 	    - Data to be written.
//		uiOffset       - Offset of the flash where data needs to be written to.
//		uiNumBytes - Number of bytes to be written.
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------

static INT BeceemEEPROMReadBackandVerify(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	UINT uiOffset,
	UINT uiNumBytes)
{
	UINT uiRdbk  	= 0;
	UINT uiIndex 	= 0;
	UINT uiData  	= 0;
	UINT auiData[4] = {0};

	while(uiNumBytes)
	{
		if(Adapter->device_removed )
		{
			return -1;
		}

		if(uiNumBytes >= MAX_RW_SIZE)
		{// for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster.
			BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);

			if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
			{
				// re-write
				BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,MAX_RW_SIZE,FALSE);
				mdelay(3);
				BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);

				if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE))
				{
					return -1;
				}
			}
			uiOffset += MAX_RW_SIZE;
			uiNumBytes -= MAX_RW_SIZE;
			uiIndex += 4;

		}
		else if(uiNumBytes >= 4)
		{
			BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4);
			if(uiData != pBuffer[uiIndex])
			{
				//re-write
				BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,4,FALSE);
				mdelay(3);
				BeceemEEPROMBulkRead(Adapter,&uiData,uiOffset,4);
				if(uiData != pBuffer[uiIndex])
				{
					return -1;
				}
			}
			uiOffset += 4;
			uiNumBytes -= 4;
			uiIndex++;

		}
		else
		{ // Handle the reads less than 4 bytes...
			uiData = 0;
			memcpy(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes);
			BeceemEEPROMBulkRead(Adapter,&uiRdbk,uiOffset,4);

			if(memcmp(&uiData, &uiRdbk, uiNumBytes))
				return -1;

			uiNumBytes = 0;
		}

	}

	return 0;
}

static VOID BcmSwapWord(UINT *ptr1) {

	UINT  tempval = (UINT)*ptr1;
	char *ptr2 = (char *)&tempval;
	char *ptr = (char *)ptr1;

	ptr[0] = ptr2[3];
	ptr[1] = ptr2[2];
	ptr[2] = ptr2[1];
	ptr[3] = ptr2[0];
}

//-----------------------------------------------------------------------------
// Procedure:	BeceemEEPROMWritePage
//
// Description: Performs page write (16bytes) to the EEPROM
//
// Arguments:
//		Adapter       - ptr to Adapter object instance
//		uiData 	  	  - Data to be written.
//		uiOffset      - Offset of the EEPROM where data needs to be written to.
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------
static INT BeceemEEPROMWritePage( PMINI_ADAPTER Adapter, UINT uiData[], UINT uiOffset )
{
	UINT uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
	UINT uiStatus = 0;
	UCHAR uiEpromStatus = 0;
	UINT value =0 ;

	/* Flush the Write/Read/Cmd queues. */
	value = ( EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH );
	wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
	value = 0 ;
	wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );

	/* Clear the Empty/Avail/Full bits.  After this it has been confirmed
	 * that the bit was cleared by reading back the register. See NOTE below.
	 * We also clear the Read queues as we do a EEPROM status register read
	 * later. */
	value = ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL ) ;
	wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));

	/* Enable write */
	value = EEPROM_WRITE_ENABLE ;
	wrmalt( Adapter, EEPROM_CMDQ_SPI_REG,&value, sizeof(value) );

	/* We can write back to back 8bits * 16 into the queue and as we have
	 * checked for the queue to be empty we can write in a burst. */

	value = uiData[0];
	BcmSwapWord(&value);
	wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);

	value = uiData[1];
	BcmSwapWord(&value);
	wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);

	value = uiData[2];
	BcmSwapWord(&value);
	wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);

	value = uiData[3];
	BcmSwapWord(&value);
	wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);

	/* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG
	 * shows that we see 7 for the EEPROM data write.  Which means that
	 * queue got full, also space is available as well as the queue is empty.
	 * This may happen in sequence. */
	value =  EEPROM_16_BYTE_PAGE_WRITE | uiOffset ;
	wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value) );

	/* Ideally we should loop here without tries and eventually succeed.
	 * What we are checking if the previous write has completed, and this
	 * may take time. We should wait till the Empty bit is set. */
	uiStatus = 0;
	rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
	while ( ( uiStatus & EEPROM_WRITE_QUEUE_EMPTY ) == 0 )
	{
		uiRetries--;
		if ( uiRetries == 0 )
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY);
			return STATUS_FAILURE ;
		}

		if( !(uiRetries%RETRIES_PER_DELAY) )
					msleep(1);

		uiStatus = 0;
		rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
		if(Adapter->device_removed == TRUE)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem got removed hence exiting from loop....");
			return -ENODEV;
		}

	}

	if ( uiRetries != 0 )
	{
		/* Clear the ones that are set - either, Empty/Full/Avail bits */
		value = ( uiStatus & ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL ) );
		wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
	}

	/* Here we should check if the EEPROM status register is correct before
	 * proceeding. Bit 0 in the EEPROM Status register should be 0 before
	 * we proceed further.  A 1 at Bit 0 indicates that the EEPROM is busy
	 * with the previous write. Note also that issuing this read finally
	 * means the previous write to the EEPROM has completed. */
	uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
	uiEpromStatus = 0;
	while ( uiRetries != 0 )
	{
		uiEpromStatus = ReadEEPROMStatusRegister( Adapter) ;
		if(Adapter->device_removed == TRUE)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
			return -ENODEV;
		}
		if ( ( EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus ) == 0 )
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY- uiRetries) );
			return STATUS_SUCCESS ;
		}
		uiRetries--;
		if ( uiRetries == 0 )
		{
			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);
			return STATUS_FAILURE ;
		}
		uiEpromStatus = 0;
		if( !(uiRetries%RETRIES_PER_DELAY) )
				msleep(1);
	}

	return STATUS_SUCCESS ;
} /* BeceemEEPROMWritePage */


//-----------------------------------------------------------------------------
// Procedure:	BeceemEEPROMBulkWrite
//
// Description: Performs write to the EEPROM
//
// Arguments:
//		Adapter       - ptr to Adapter object instance
//		pBuffer 	    - Data to be written.
//		uiOffset       - Offset of the EEPROM where data needs to be written to.
//		uiNumBytes - Number of bytes to be written.
//		bVerify        - read verify flag.
// Returns:
//		OSAL_STATUS_CODE
//
//-----------------------------------------------------------------------------

INT BeceemEEPROMBulkWrite(
	PMINI_ADAPTER Adapter,
	PUCHAR pBuffer,
	UINT uiOffset,
	UINT uiNumBytes,
	BOOLEAN bVerify)
{
	UINT  uiBytesToCopy = uiNumBytes;
	//UINT  uiRdbk 		= 0;
	UINT  uiData[4] 	= {0};
	UINT  uiIndex 		= 0;
	UINT  uiTempOffset  = 0;
	UINT  uiExtraBytes  = 0;
	//PUINT puiBuffer 	= (PUINT)pBuffer;
	//INT value;

	if(uiOffset%MAX_RW_SIZE && uiBytesToCopy)
	{
		uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
		uiExtraBytes = uiOffset-uiTempOffset;


		BeceemEEPROMBulkRead(Adapter,&uiData[0],uiTempOffset,MAX_RW_SIZE);

		if(uiBytesToCopy >= (16 -uiExtraBytes))
		{
			memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes);

			if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
					return STATUS_FAILURE;

			uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes);
			uiIndex += (MAX_RW_SIZE - uiExtraBytes);
			uiOffset += (MAX_RW_SIZE - uiExtraBytes);
		}
		else
		{
			memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy);

			if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) )
					return STATUS_FAILURE;

			uiIndex += uiBytesToCopy;
			uiOffset += uiBytesToCopy;
			uiBytesToCopy = 0;
		}


	}

	while(uiBytesToCopy)
	{
		if(Adapter->device_removed)
		{
			return -1;
		}

		if(uiBytesToCopy >= MAX_RW_SIZE)
		{

			if (STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, (PUINT) &pBuffer[uiIndex], uiOffset ) )
						return STATUS_FAILURE;

			uiIndex += MAX_RW_SIZE;
			uiOffset += MAX_RW_SIZE;
			uiBytesToCopy	-= MAX_RW_SIZE;
		}
		else
		{
	//
	// To program non 16byte aligned data, read 16byte and then update.
	//
			BeceemEEPROMBulkRead(Adapter,&uiData[0],uiOffset,16);
			memcpy(&uiData[0],pBuffer+uiIndex,uiBytesToCopy);


			if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiOffset ) )
					return STATUS_FAILURE;
			uiBytesToCopy = 0;
		}

	}

	return 0;
}

//-----------------------------------------------------------------------------
// Procedure:	BeceemNVMRead
//
// Description: Reads n number of bytes from NVM.
//
// Arguments:
//		Adapter      - ptr to Adapter object instance
//		pBuffer       - Buffer to store the data read from NVM
//		uiOffset       - Offset of NVM from where data should be read
//		uiNumBytes - Number of bytes to be read from the NVM.
//
// Returns:
//		OSAL_STATUS_SUCCESS - if NVM read is successfull.
//		<FAILURE>			- if failed.
//-----------------------------------------------------------------------------

INT BeceemNVMRead(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	UINT uiOffset,
	UINT uiNumBytes)
{
	INT Status = 0;
#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
	UINT uiTemp = 0, value;
#endif

	if(Adapter->eNVMType == NVM_FLASH)
	{
		if(Adapter->bFlashRawRead == FALSE)
		{
			if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
				return vendorextnReadSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes);
			uiOffset = uiOffset+ Adapter->ulFlashCalStart ;
		}
#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
		Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
#else

		rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
		value = 0;
		wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
		Status = BeceemFlashBulkRead(Adapter,
						pBuffer,
						uiOffset,
						uiNumBytes);
		wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
#endif
	}
	else if(Adapter->eNVMType == NVM_EEPROM)
	{
		Status = BeceemEEPROMBulkRead(Adapter,
					pBuffer,
					uiOffset,
					uiNumBytes);
	}
	else
	{
		Status = -1;
	}
	return Status;
}

//-----------------------------------------------------------------------------
// Procedure:	BeceemNVMWrite
//
// Description: Writes n number of bytes to NVM.
//
// Arguments:
//		Adapter      - ptr to Adapter object instance
//		pBuffer       - Buffer contains the data to be written.
//		uiOffset       - Offset of NVM where data to be written to.
//		uiNumBytes - Number of bytes to be written..
//
// Returns:
//		OSAL_STATUS_SUCCESS - if NVM write is successfull.
//		<FAILURE>			- if failed.
//-----------------------------------------------------------------------------

INT BeceemNVMWrite(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	UINT uiOffset,
	UINT uiNumBytes,
	BOOLEAN bVerify)
{
	INT Status = 0;
	UINT uiTemp = 0;
	UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
	UINT uiIndex = 0;
#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
	UINT value;
#endif
	UINT uiFlashOffset = 0;

	if(Adapter->eNVMType == NVM_FLASH)
	{
		if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
			Status = vendorextnWriteSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes,bVerify);
		else
		{
			uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;

#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
			Status = bcmflash_raw_write((uiFlashOffset/FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer,uiNumBytes);
#else
			rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
			value = 0;
			wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));

			if(Adapter->bStatusWrite == TRUE)
			{
				Status = BeceemFlashBulkWriteStatus(Adapter,
							pBuffer,
							uiFlashOffset,
							uiNumBytes ,
							bVerify);
			}
			else
			{

				Status = BeceemFlashBulkWrite(Adapter,
							pBuffer,
							uiFlashOffset,
							uiNumBytes,
							bVerify);
			}
#endif
		}


		if(uiOffset >= EEPROM_CALPARAM_START)
		{
			uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
			while(uiNumBytes)
			{
				if(uiNumBytes > BUFFER_4K)
				{
					wrm(Adapter,(uiMemoryLoc+uiIndex),(PCHAR)(pBuffer+(uiIndex/4)),BUFFER_4K);
					uiNumBytes -= BUFFER_4K;
					uiIndex += BUFFER_4K;
				}
				else
				{
					wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)(pBuffer+(uiIndex/4)),uiNumBytes);
					uiNumBytes = 0;
					break;
				}
			}
		}
		else
		{
			if((uiOffset+uiNumBytes) > EEPROM_CALPARAM_START)
			{
				ULONG ulBytesTobeSkipped = 0;
				PUCHAR pcBuffer = (PUCHAR)pBuffer;// char pointer to take care of odd byte cases.
				uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
				ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
				uiOffset += (EEPROM_CALPARAM_START - uiOffset);
				while(uiNumBytes)
				{
					if(uiNumBytes > BUFFER_4K)
					{
						wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR )&pcBuffer[ulBytesTobeSkipped+uiIndex],BUFFER_4K);
						uiNumBytes -= BUFFER_4K;
						uiIndex += BUFFER_4K;
					}
					else
					{
						wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)&pcBuffer[ulBytesTobeSkipped+uiIndex],uiNumBytes);
						uiNumBytes = 0;
						break;
					}
				}

			}
		}

	// restore the values.
		wrmalt(Adapter,0x0f000C80,&uiTemp, sizeof(uiTemp));
	}
	else if(Adapter->eNVMType == NVM_EEPROM)
	{
		Status = BeceemEEPROMBulkWrite(Adapter,
					(PUCHAR)pBuffer,
					uiOffset,
					uiNumBytes,
					bVerify);
		if(bVerify)
		{
			Status = BeceemEEPROMReadBackandVerify(Adapter,(PUINT)pBuffer,uiOffset,uiNumBytes);
		}
	}
	else
	{
		Status = -1;
	}
	return Status;
}

//-----------------------------------------------------------------------------
// Procedure:	BcmUpdateSectorSize
//
// Description: Updates the sector size to FLASH.
//
// Arguments:
//		Adapter       - ptr to Adapter object instance
//          uiSectorSize - sector size
//
// Returns:
//		OSAL_STATUS_SUCCESS - if NVM write is successfull.
//		<FAILURE>			- if failed.
//-----------------------------------------------------------------------------

INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize)
{
	INT Status = -1;
	FLASH_CS_INFO sFlashCsInfo = {0};
	UINT uiTemp = 0;

	UINT uiSectorSig = 0;
	UINT uiCurrentSectorSize = 0;

	UINT value;



	rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
	value = 0;
	wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));

//
// Before updating the sector size in the reserved area, check if already present.
//
	BeceemFlashBulkRead(Adapter,(PUINT)&sFlashCsInfo,Adapter->ulFlashControlSectionStart,sizeof(sFlashCsInfo));
	uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
	uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);

	if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
	{

		if((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE))
		{
			if(uiSectorSize == uiCurrentSectorSize)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Provided sector size is same as programmed in Flash");
				Status = STATUS_SUCCESS;
				goto Restore ;
			}
		}
	}

	if((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE))
	{

		sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize);
		sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG);

		Status = BeceemFlashBulkWrite(Adapter,
					(PUINT)&sFlashCsInfo,
					Adapter->ulFlashControlSectionStart,
					sizeof(sFlashCsInfo),
					TRUE);


	}

	Restore :
	// restore the values.
	wrmalt(Adapter, 0x0f000C80,&uiTemp, sizeof(uiTemp));


	return Status;

}

//-----------------------------------------------------------------------------
// Procedure:	BcmGetFlashSectorSize
//
// Description: Finds the sector size of the FLASH.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//
// Returns:
//		UINT - sector size.
//
//-----------------------------------------------------------------------------

static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize)
{
	UINT uiSectorSize = 0;
	UINT uiSectorSig = 0;

	if(Adapter->bSectorSizeOverride &&
		(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
		Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE))
	{
		Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
	}
	else
	{

		uiSectorSig = FlashSectorSizeSig;

		if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
		{
			uiSectorSize = FlashSectorSize;
	//
	// If the sector size stored in the FLASH makes sense then use it.
	//
			if(uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE)
			{
				Adapter->uiSectorSize = uiSectorSize;
			}
	//No valid size in FLASH, check if Config file has it.
			else if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
					Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
			{
				Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
			}
	// Init to Default, if none of the above works.
			else
			{
				Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
			}

		}
		else
		{
			if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
					Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
			{
				Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
			}
			else
			{
				Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
			}
		}
	}

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size  :%x \n", Adapter->uiSectorSize);
	return Adapter->uiSectorSize;
}

//-----------------------------------------------------------------------------
// Procedure:	BcmInitEEPROMQueues
//
// Description: Initialization of EEPROM queues.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//
// Returns:
//		<OSAL_STATUS_CODE>
//-----------------------------------------------------------------------------

static INT BcmInitEEPROMQueues(PMINI_ADAPTER Adapter)
{
	UINT value = 0;
	/* CHIP Bug : Clear the Avail bits on the Read queue. The default
	 * value on this register is supposed to be 0x00001102.
	 * But we get 0x00001122. */
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Fixing reset value on 0x0f003004 register\n" );
	value = EEPROM_READ_DATA_AVAIL;
	wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));

	/* Flush the all the EEPROM queues. */
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n");
	value =EEPROM_ALL_QUEUE_FLUSH ;
	wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));

	value = 0;
	wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );

	/* Read the EEPROM Status Register. Just to see, no real purpose. */
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter) );

	return STATUS_SUCCESS;
} /* BcmInitEEPROMQueues() */

//-----------------------------------------------------------------------------
// Procedure:	BcmInitNVM
//
// Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//
// Returns:
//		<OSAL_STATUS_CODE>
//-----------------------------------------------------------------------------

INT BcmInitNVM(PMINI_ADAPTER ps_adapter)
{
	BcmValidateNvmType(ps_adapter);
	BcmInitEEPROMQueues(ps_adapter);

	if(ps_adapter->eNVMType == NVM_AUTODETECT)
	{
		ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
		if(ps_adapter->eNVMType == NVM_UNKNOWN)
		{
			BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
		}
	}
	else if(ps_adapter->eNVMType == NVM_FLASH)
	{
		BcmGetFlashCSInfo(ps_adapter);
	}

	BcmGetNvmSize(ps_adapter);

	return STATUS_SUCCESS;
}
/***************************************************************************/
/*BcmGetNvmSize : set the EEPROM or flash size in Adapter.
*
*Input Parameter:
*		Adapter data structure
*Return Value :
*		0. means sucess;
*/
/***************************************************************************/

static INT BcmGetNvmSize(PMINI_ADAPTER Adapter)
{
	if(Adapter->eNVMType == NVM_EEPROM)
	{
		Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
	}
	else if(Adapter->eNVMType == NVM_FLASH)
	{
		Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
	}
	return 0;
}

//-----------------------------------------------------------------------------
// Procedure:	BcmValidateNvm
//
// Description: Validates the NVM Type option selected against the device
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//
// Returns:
//		<VOID>
//-----------------------------------------------------------------------------
static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter)
{

	//
	// if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
	// Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
	// So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
	//

	if(Adapter->eNVMType == NVM_FLASH &&
		Adapter->chip_id < 0xBECE3300)
	{
		Adapter->eNVMType = NVM_AUTODETECT;
	}
}
//-----------------------------------------------------------------------------
// Procedure:	BcmReadFlashRDID
//
// Description: Reads ID from Serial Flash
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//
// Returns:
//		Flash ID
//-----------------------------------------------------------------------------
static ULONG BcmReadFlashRDID(PMINI_ADAPTER Adapter)
{
	ULONG ulRDID = 0;
	UINT value;
//
// Read ID Instruction.
//
	value = (FLASH_CMD_READ_ID<<24);
	wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value));

//Delay
	udelay(10);
//
// Read SPI READQ REG. The output will be WWXXYYZZ.
// The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
//
	rdmalt(Adapter, FLASH_SPI_READQ_REG,(PUINT)&ulRDID, sizeof(ulRDID));

	return (ulRDID >>8);


}

INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
{
	if(psAdapter == NULL)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
		return -EINVAL;
	}
	psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL);
	if(psAdapter->psFlashCSInfo == NULL)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 1.x");
		return -ENOMEM;
	}

	psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL);
	if(psAdapter->psFlash2xCSInfo == NULL)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x");
		kfree(psAdapter->psFlashCSInfo);
		return -ENOMEM;
	}

	psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL);
	if(psAdapter->psFlash2xVendorInfo == NULL)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x");
		kfree(psAdapter->psFlashCSInfo);
		kfree(psAdapter->psFlash2xCSInfo);
		return -ENOMEM;
	}

	return STATUS_SUCCESS;
}

INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
{
	if(psAdapter == NULL)
	{
		BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL");
		return -EINVAL;
	}
	kfree(psAdapter->psFlashCSInfo);
	kfree(psAdapter->psFlash2xCSInfo);
	kfree(psAdapter->psFlash2xVendorInfo);
	return STATUS_SUCCESS ;
}

static INT	BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,PMINI_ADAPTER Adapter)
{
	UINT Index = 0;
    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is  :%x", (psFlash2xCSInfo->MagicNumber));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware  :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware ));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End	:0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
	for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
	{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
				(psFlash2xCSInfo->SectorAccessBitMap[Index]));
	}

	return STATUS_SUCCESS;
}


static INT	ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo)
{
	UINT Index = 0;
	psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
	psFlash2xCSInfo->FlashLayoutVersion= ntohl(psFlash2xCSInfo->FlashLayoutVersion);
	//psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion);
	psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
	psFlash2xCSInfo->SCSIFirmwareVersion =ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
	psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
	psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
	psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware );
	psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
	psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
	psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
	psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
	psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
	psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
	psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
	psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
	psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
	psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
	psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
	psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
	psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
	psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
	psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
	psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
	psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
	psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
	psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
	psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
	psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
	psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
	psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
	psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
	psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
	psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
	psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
	psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
	psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
	psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
	psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
	psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
	psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
	psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
	psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
	psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
	psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
	psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
	for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
	{
			psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
	}
	return STATUS_SUCCESS;
}

static INT	ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo)
{
	//UINT Index = 0;
	psFlashCSInfo->MagicNumber					 		=ntohl(psFlashCSInfo->MagicNumber);
	psFlashCSInfo->FlashLayoutVersion					=ntohl(psFlashCSInfo->FlashLayoutVersion);
	psFlashCSInfo->ISOImageVersion 						= ntohl(psFlashCSInfo->ISOImageVersion);
	//won't convert according to old assumption
	psFlashCSInfo->SCSIFirmwareVersion =(psFlashCSInfo->SCSIFirmwareVersion);

	psFlashCSInfo->OffsetFromZeroForPart1ISOImage  		= ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
	psFlashCSInfo->OffsetFromZeroForScsiFirmware        = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
	psFlashCSInfo->SizeOfScsiFirmware                   = ntohl(psFlashCSInfo->SizeOfScsiFirmware );
	psFlashCSInfo->OffsetFromZeroForPart2ISOImage       = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
	psFlashCSInfo->OffsetFromZeroForCalibrationStart    = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
	psFlashCSInfo->OffsetFromZeroForCalibrationEnd      = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
	psFlashCSInfo->OffsetFromZeroForVSAStart            = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
	psFlashCSInfo->OffsetFromZeroForVSAEnd              = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
	psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
	psFlashCSInfo->OffsetFromZeroForControlSectionData  = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
	psFlashCSInfo->CDLessInactivityTimeout 				= ntohl(psFlashCSInfo->CDLessInactivityTimeout);
	psFlashCSInfo->NewImageSignature                    = ntohl(psFlashCSInfo->NewImageSignature);
	psFlashCSInfo->FlashSectorSizeSig                   = ntohl(psFlashCSInfo->FlashSectorSizeSig);
	psFlashCSInfo->FlashSectorSize                      = ntohl(psFlashCSInfo->FlashSectorSize);
	psFlashCSInfo->FlashWriteSupportSize                = ntohl(psFlashCSInfo->FlashWriteSupportSize);
	psFlashCSInfo->TotalFlashSize        				= ntohl(psFlashCSInfo->TotalFlashSize);
 	psFlashCSInfo->FlashBaseAddr         				= ntohl(psFlashCSInfo->FlashBaseAddr);
	psFlashCSInfo->FlashPartMaxSize      				= ntohl(psFlashCSInfo->FlashPartMaxSize);
 	psFlashCSInfo->IsCDLessDeviceBootSig 				= ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
	psFlashCSInfo->MassStorageTimeout    				= ntohl(psFlashCSInfo->MassStorageTimeout);

	return STATUS_SUCCESS;
}

static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
{
 	return ( Adapter->uiVendorExtnFlag &&
 		(Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
 		(Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS) );
}

static VOID UpdateVendorInfo(PMINI_ADAPTER Adapter)
{
	B_UINT32 i = 0;
	UINT uiSizeSection = 0;

	Adapter->uiVendorExtnFlag = FALSE;

	for(i = 0;i < TOTAL_SECTIONS;i++)
		Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;

	if(STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
		return;

	i = 0;
	while(i < TOTAL_SECTIONS)
	{
		if(!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT))
		{
			i++;
			continue;
		}

		Adapter->uiVendorExtnFlag = TRUE;
		uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
						Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);

		switch(i)
		{
		case DSD0:
			if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
			(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
				Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
			else
				Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
			break;

		case DSD1:
			if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
			(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
				Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
			else
				Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
			break;

		case DSD2:
			if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
			(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
				Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
			else
				Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
			break;
		case VSA0:
			if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
				Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
			else
				Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
			break;

		case VSA1:
			if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
				Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
			else
				Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
			break;
		case VSA2:
			if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
				Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
			else
				Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
			break;

		default:
			break;
		}
		i++;
	}

}

//-----------------------------------------------------------------------------
// Procedure:	BcmGetFlashCSInfo
//
// Description: Reads control structure and gets Cal section addresses.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//
// Returns:
//		<VOID>
//-----------------------------------------------------------------------------

static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter)
{
	//FLASH_CS_INFO sFlashCsInfo = {0};

#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
	UINT value;
#endif
	UINT uiFlashLayoutMajorVersion;
	Adapter->uiFlashLayoutMinorVersion = 0;
	Adapter->uiFlashLayoutMajorVersion = 0;
	Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;


	Adapter->uiFlashBaseAdd = 0;
	Adapter->ulFlashCalStart = 0;
	memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO));
	memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO));

	if(!Adapter->bDDRInitDone)
	{
		{
			value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
			wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
		}
	}


	// Reading first 8 Bytes to get the Flash Layout
	// MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
	BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,8);

	Adapter->psFlashCSInfo->FlashLayoutVersion =  ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion));
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is  :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));

	if(FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber))
	{
		uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
		Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
	}
	else
	{
		Adapter->uiFlashLayoutMinorVersion = 0;
		uiFlashLayoutMajorVersion = 0;
	}

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);

	if(uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER)
	{
		BeceemFlashBulkRead(Adapter,(PUINT)Adapter->psFlashCSInfo,Adapter->ulFlashControlSectionStart,sizeof(FLASH_CS_INFO));
		ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
		Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);

		if(!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
		{
			Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
		}

		if((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) &&
		   (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) &&
		   (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) &&
		   (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize)))
		{
			Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
		   	Adapter->fpFlashWrite = flashByteWrite;
		   	Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
		}
		else
		{
			Adapter->ulFlashWriteSize = MAX_RW_SIZE;
			Adapter->fpFlashWrite = flashWrite;
		   	Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
		}

		BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
					 (Adapter->psFlashCSInfo->FlashSectorSize));


		Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;


	}
	else
	{
		if(BcmFlash2xBulkRead(Adapter,(PUINT)Adapter->psFlash2xCSInfo,NO_SECTION_VAL,
				Adapter->ulFlashControlSectionStart,sizeof(FLASH2X_CS_INFO)))
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure \n");
			return STATUS_FAILURE;
		}
		ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
		BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter);
		if((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
		   (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
		   (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
		   (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize))
		{
			Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
		   	Adapter->fpFlashWrite = flashByteWrite;
		   	Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
		}
		else
		{
			Adapter->ulFlashWriteSize = MAX_RW_SIZE;
			Adapter->fpFlashWrite = flashWrite;
		   	Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
		}

		BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
					Adapter->psFlash2xCSInfo->FlashSectorSize);

		UpdateVendorInfo(Adapter);

		BcmGetActiveDSD(Adapter);
		BcmGetActiveISO(Adapter);
		Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
		Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;

	}
	/*
	Concerns: what if CS sector size does not match with this sector size ???
	what is the indication of AccessBitMap  in CS in flash 2.x ????
	*/
	Adapter->ulFlashID = BcmReadFlashRDID(Adapter);

	Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;


	return STATUS_SUCCESS ;
}


//-----------------------------------------------------------------------------
// Procedure:	BcmGetNvmType
//
// Description: Finds the type of NVM used.
//
// Arguments:
//		Adapter    - ptr to Adapter object instance
//
// Returns:
//		NVM_TYPE
//
//-----------------------------------------------------------------------------

static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter)
{
	UINT uiData = 0;

	BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
	if(uiData == BECM)
	{
		return NVM_EEPROM;
	}
	//
	// Read control struct and get cal addresses before accessing the flash
	//
	BcmGetFlashCSInfo(Adapter);

	BeceemFlashBulkRead(Adapter,&uiData,0x0 + Adapter->ulFlashCalStart,4);
	if(uiData == BECM)
	{
		return NVM_FLASH;
	}
//
// even if there is no valid signature on EEPROM/FLASH find out if they really exist.
// if exist select it.
//
	if(BcmGetEEPROMSize(Adapter))
	{
		return NVM_EEPROM;
	}

//TBD for Flash.


	return NVM_UNKNOWN;
}

/**
*	BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
*	@Adapter : Drivers Private Data structure
*	@eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
*
*	Return value:-
*	On success it return the start offset of the provided section val
*	On Failure -returns STATUS_FAILURE
**/

INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
{
	/*
	*	Considering all the section for which end offset can be calculated or directly given
	*	in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
	*	endoffset can't be calculated or given in CS Stucture.
	*/

	INT SectStartOffset = 0 ;

	SectStartOffset = INVALID_OFFSET ;

	if(IsSectionExistInVendorInfo(Adapter,eFlashSectionVal))
	{
		return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
	}

	switch(eFlashSectionVal)
	{
		case ISO_IMAGE1 :
			  if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
			  	(IsNonCDLessDevice(Adapter) == FALSE))
				  SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
			   break;
		case ISO_IMAGE2 :
				if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
					(IsNonCDLessDevice(Adapter) == FALSE))
			  		SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
			  break;
		case DSD0 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
					SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
				break;
		case DSD1 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
					SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
				break;
		case DSD2 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
					SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
				break;
		case VSA0 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
					SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
				break;
		case VSA1 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
					SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
				break;
		case VSA2 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
					SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
				break;
		case SCSI :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
					SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
				break;
		case CONTROL_SECTION :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
					SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
				break;
		case ISO_IMAGE1_PART2 :
				if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
				 	 SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
				 break;
		case ISO_IMAGE1_PART3 :
				if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
				  SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
			  	break;
		case ISO_IMAGE2_PART2 :
				if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
			 		 SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
			    break;
		case ISO_IMAGE2_PART3 :
  			  if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
  				  SectStartOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
  			  break;
		default :
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
			SectStartOffset =  INVALID_OFFSET;
	}
	return SectStartOffset;
}

/**
*	BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
*	@Adapter : Drivers Private Data structure
*	@eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
*
*	Return value:-
*	On success it return the end offset of the provided section val
*	On Failure -returns STATUS_FAILURE
**/

INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
{
	INT SectEndOffset = 0 ;
	SectEndOffset = INVALID_OFFSET;

	if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
	{
		return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
	}

	switch(eFlash2xSectionVal)
	{
		case ISO_IMAGE1 :
			 if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End!= UNINIT_PTR_IN_CS) &&
			 	 (IsNonCDLessDevice(Adapter) == FALSE))
				  SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
			   break;
		case ISO_IMAGE2 :
			if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End!= UNINIT_PTR_IN_CS) &&
				(IsNonCDLessDevice(Adapter) == FALSE))
					SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
			 break;
		case DSD0 :
			if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
				SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
			break;
		case DSD1 :
			if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
				SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
			break;
		case DSD2 :
			if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
				SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
			break;
		case VSA0 :
			if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
				SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
			break;
		case VSA1 :
			if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
				SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
			break;
		case VSA2 :
			if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
				SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
			break;
		case SCSI :
			if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
				SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
					(Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
			break;
		case CONTROL_SECTION :
				//Not Clear So Putting failure. confirm and fix it.
				SectEndOffset = STATUS_FAILURE;
		case ISO_IMAGE1_PART2 :
				if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End!= UNINIT_PTR_IN_CS)
				 	 SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
				 break;
		case ISO_IMAGE1_PART3 :
				if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End!= UNINIT_PTR_IN_CS)
				  SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
			  	break;
		case ISO_IMAGE2_PART2 :
				if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
			 		 SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
			    break;
		case ISO_IMAGE2_PART3 :
  			  if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End!= UNINIT_PTR_IN_CS)
  				  SectEndOffset =  (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
  			  break;

		default :
			SectEndOffset = INVALID_OFFSET;
	}
	return SectEndOffset ;
}

/*
*	BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
*	@Adapter :Driver Private Data Structure
*	@pBuffer : Buffer where data has to be put after reading
*	@eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
*	@uiOffsetWithinSectionVal :- Offset with in provided section
*	@uiNumBytes : Number of Bytes for Read
*
*	Return value:-
*		return true on sucess and STATUS_FAILURE on fail.
*/

INT BcmFlash2xBulkRead(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	FLASH2X_SECTION_VAL eFlash2xSectionVal,
	UINT uiOffsetWithinSectionVal,
	UINT uiNumBytes)
{

	INT Status = STATUS_SUCCESS;
	INT SectionStartOffset = 0;
	UINT uiAbsoluteOffset = 0 ;
	UINT uiTemp =0, value =0 ;
	if(Adapter == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
		return -EINVAL;
	}
	if(Adapter->device_removed )
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
		return -ENODEV;
	}

	//NO_SECTION_VAL means absolute offset is given.
	if(eFlash2xSectionVal == NO_SECTION_VAL)
		SectionStartOffset = 0;
	else
		SectionStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);

	if(SectionStartOffset == STATUS_FAILURE )
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash 2.x Map ",eFlash2xSectionVal);
		return -EINVAL;
	}

	if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
		return vendorextnReadSection(Adapter,(PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);

	//calculating  the absolute offset from FLASH;
	uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
	rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
	value = 0;
	wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));

	Status= BeceemFlashBulkRead(Adapter, pBuffer,uiAbsoluteOffset,uiNumBytes) ;

	wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
	if(Status)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
		return Status ;
	}

	return Status;
}

/*
*	BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
*	@Adapter :Driver Private Data Structure
*	@pBuffer : Buffer From where data has to taken for writing
*	@eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
*	@uiOffsetWithinSectionVal :- Offset with in provided section
*	@uiNumBytes : Number of Bytes for Write
*
*	Return value:-
*		return true on sucess and STATUS_FAILURE on fail.
*
*/

INT BcmFlash2xBulkWrite(
	PMINI_ADAPTER Adapter,
	PUINT pBuffer,
	FLASH2X_SECTION_VAL eFlash2xSectVal,
	UINT uiOffset,
	UINT uiNumBytes,
	UINT bVerify)
{

	INT Status 	= STATUS_SUCCESS;
	UINT FlashSectValStartOffset = 0;
	UINT uiTemp = 0, value = 0;
	if(Adapter == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
		return -EINVAL;
	}
	if(Adapter->device_removed )
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
		return -ENODEV;
	}

	//NO_SECTION_VAL means absolute offset is given.
	if(eFlash2xSectVal == NO_SECTION_VAL)
		FlashSectValStartOffset = 0;
	else
		FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectVal);

	if(FlashSectValStartOffset == STATUS_FAILURE )
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash Map 2.x",eFlash2xSectVal);
		return -EINVAL;
	}

	if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectVal))
		return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);

	//calculating  the absolute offset from FLASH;
	uiOffset = uiOffset + FlashSectValStartOffset;

	rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
	value = 0;
	wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));

	Status = BeceemFlashBulkWrite(Adapter, pBuffer,uiOffset,uiNumBytes,bVerify);

	wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
	if(Status)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
		return Status ;
	}

	return Status;

}

/**
*	BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
*	@Adapter :-Drivers private Data Structure
*
*	Return Value:-
*		Return STATUS_SUCESS if get sucess in setting the right DSD else negaive error code
*
**/
static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter)
{
	FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;

	uiHighestPriDSD = getHighestPriDSD(Adapter);
	Adapter->eActiveDSD = uiHighestPriDSD;

	if(DSD0  == uiHighestPriDSD)
		Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
	if(DSD1 == uiHighestPriDSD)
		Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
	if(DSD2 == uiHighestPriDSD)
		Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
	if(Adapter->eActiveDSD)
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
	if(Adapter->eActiveDSD == 0)
	{
		//if No DSD gets Active, Make Active the DSD with WR  permission
		if(IsSectionWritable(Adapter,DSD2))
		{
			Adapter->eActiveDSD = DSD2;
			Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
		}
		else if(IsSectionWritable(Adapter,DSD1))
		{
			Adapter->eActiveDSD = DSD1;
			Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
		}
		else if(IsSectionWritable(Adapter,DSD0))
		{
			Adapter->eActiveDSD = DSD0;
			Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
		}
	}

	return STATUS_SUCCESS;
}


/**
*	BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
*	@Adapter : Driver private Data Structure
*
*	Return Value:-
*		Sucsess:- STATUS_SUCESS
*		Failure- : negative erro code
*
**/

static INT BcmGetActiveISO(PMINI_ADAPTER Adapter)
{

	INT HighestPriISO = 0 ;
	HighestPriISO = getHighestPriISO(Adapter);

	Adapter->eActiveISO = HighestPriISO ;
	if(Adapter->eActiveISO == ISO_IMAGE2)
		Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
	else if(Adapter->eActiveISO == ISO_IMAGE1)
		Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);

	if(Adapter->eActiveISO)
	 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Active ISO :%x", Adapter->eActiveISO);

	return STATUS_SUCCESS;
}

/**
*	IsOffsetWritable :- it will tell the access permission of the sector having passed offset
*	@Adapter : Drivers Private Data Structure
*	@uiOffset : Offset provided in the Flash
*
*	Return Value:-
*	Sucess:-TRUE ,  offset is writable
*	Failure:-FALSE, offset is RO
*
**/
B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset)
{
	UINT uiSectorNum = 0;
	UINT uiWordOfSectorPermission =0;
	UINT uiBitofSectorePermission = 0;
	B_UINT32 permissionBits = 0;
	uiSectorNum = uiOffset/Adapter->uiSectorSize;

	//calculating the word having this Sector Access permission from SectorAccessBitMap Array
	uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum /16];

	//calculating the bit index inside the word for  this sector
	uiBitofSectorePermission = 2*(15 - uiSectorNum %16);

	//Setting Access permission
	permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission) ;
	permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
	if(permissionBits == SECTOR_READWRITE_PERMISSION)
		return 	TRUE;
	else
		return FALSE;
}

static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
{
    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE1  :0X%x", psFlash2xBitMap->ISO_IMAGE1);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE2  :0X%x", psFlash2xBitMap->ISO_IMAGE2);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD0  :0X%x", psFlash2xBitMap->DSD0);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD1  :0X%x", psFlash2xBitMap->DSD1);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD2  :0X%x", psFlash2xBitMap->DSD2);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA0  :0X%x", psFlash2xBitMap->VSA0);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA1  :0X%x", psFlash2xBitMap->VSA1);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA2  :0X%x", psFlash2xBitMap->VSA2);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"SCSI  :0X%x", psFlash2xBitMap->SCSI);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"CONTROL_SECTION  :0X%x", psFlash2xBitMap->CONTROL_SECTION);

	return STATUS_SUCCESS;
}

/**
*	BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
*	8bit has been assigned to every section.
	bit[0] :Section present or not
	bit[1] :section is valid or not
	bit[2] : Secton is read only or has write permission too.
	bit[3] : Active Section -
	bit[7...4] = Reserved .

	@Adapter:-Driver private Data Structure
*
*	Return value:-
*	Sucess:- STATUS_SUCESS
*	Failure:- negative error code
**/

INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap)
{


	PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
	FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
	FLASH2X_SECTION_VAL uiHighestPriISO= 0 ;
	BOOLEAN SetActiveDSDDone = FALSE ;
	BOOLEAN SetActiveISODone = FALSE ;

	//For 1.x map all the section except DSD0 will be shown as not present
	//This part will be used by calibration tool to detect the number of DSD present in Flash.
	if(IsFlash2x(Adapter) == FALSE)
	{
		psFlash2xBitMap->ISO_IMAGE2 = 0;
		psFlash2xBitMap->ISO_IMAGE1 = 0;
		psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF;   //0000(Reseved)1(Active)0(RW)1(valid)1(present)
		psFlash2xBitMap->DSD1  = 0 ;
		psFlash2xBitMap->DSD2 = 0 ;
		psFlash2xBitMap->VSA0 = 0 ;
		psFlash2xBitMap->VSA1 = 0 ;
		psFlash2xBitMap->VSA2 = 0 ;
		psFlash2xBitMap->CONTROL_SECTION = 0 ;
		psFlash2xBitMap->SCSI= 0 ;
		psFlash2xBitMap->Reserved0 = 0 ;
		psFlash2xBitMap->Reserved1 = 0 ;
		psFlash2xBitMap->Reserved2 = 0 ;
		return STATUS_SUCCESS ;

	}

	uiHighestPriDSD = getHighestPriDSD(Adapter);
	uiHighestPriISO = getHighestPriISO(Adapter);

	///
	//	IS0 IMAGE 2
	///
	if((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->ISO_IMAGE2= psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;


		if(ReadISOSignature(Adapter,ISO_IMAGE2)== ISO_IMAGE_MAGIC_NUMBER)
			psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;


		//Calculation for extrating the Access permission
		if(IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
			psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;

		if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2)
		{
			psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT ;
			SetActiveISODone = TRUE;
		}

	}

	///
	//	IS0 IMAGE 1
	///
	if((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;

		if(ReadISOSignature(Adapter,ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
			psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;

		//	Calculation for extrating the Access permission
		if(IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
			psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;

		if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1)
		{
			psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT ;
			SetActiveISODone = TRUE;
		}
	}



	///
	// DSD2
	///
	if((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->DSD2= psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;

		if(ReadDSDSignature(Adapter,DSD2)== DSD_IMAGE_MAGIC_NUMBER)
			psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;

		//Calculation for extrating the Access permission
		if(IsSectionWritable(Adapter, DSD2) == FALSE)
		{
			psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;

		}
		else
		{
			//Means section is writable
			if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2))
			{
				psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT ;
				SetActiveDSDDone =TRUE ;
			}
		}
	}

	///
	//	DSD 1
	///
	if((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->DSD1= psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;


		if(ReadDSDSignature(Adapter,DSD1)== DSD_IMAGE_MAGIC_NUMBER)
			psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;

		//Calculation for extrating the Access permission
		if(IsSectionWritable(Adapter, DSD1) == FALSE)
		{
			psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
		}
		else
		{
			//Means section is writable
			if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1))
			{
					psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT ;
					SetActiveDSDDone =TRUE ;
			}
		}

	}

	///
	//For DSD 0
	//
	if((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;

		if(ReadDSDSignature(Adapter,DSD0) == DSD_IMAGE_MAGIC_NUMBER)
			psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;

		//Setting Access permission
		if(IsSectionWritable(Adapter, DSD0) == FALSE)
		{
			psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
		}
		else
		{
			//Means section is writable
			if((SetActiveDSDDone == FALSE) &&(uiHighestPriDSD == DSD0))
			{
					psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT ;
					SetActiveDSDDone =TRUE ;
			}
		}
	}

	///
	// 	VSA 0
	///
	if((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->VSA0= psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;

		//Setting the Access Bit. Map is not defined hece setting it always valid
		psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;

		//Calculation for extrating the Access permission
		if(IsSectionWritable(Adapter, VSA0) == FALSE)
			psFlash2xBitMap->VSA0 |=  FLASH2X_SECTION_RO;

		//By Default section is Active
		psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT ;

	}


	///
	//	 VSA 1
	///

	if((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->VSA1= psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;

		//Setting the Access Bit. Map is not defined hece setting it always valid
		psFlash2xBitMap->VSA1|= FLASH2X_SECTION_VALID;

		//Checking For Access permission
		if(IsSectionWritable(Adapter, VSA1) == FALSE)
			psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;

		//By Default section is Active
		psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT ;

	}


	///
	//	VSA 2
	///

	if((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->VSA2= psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;


		//Setting the Access Bit. Map is not defined hece setting it always valid
		psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;

		//Checking For Access permission
		if(IsSectionWritable(Adapter, VSA2) == FALSE)
			psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;

		//By Default section is Active
		psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT ;
	}

	///
	// SCSI Section
	///
	if((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->SCSI= psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;


		//Setting the Access Bit. Map is not defined hece setting it always valid
		psFlash2xBitMap->SCSI|= FLASH2X_SECTION_VALID;

		//Checking For Access permission
		if(IsSectionWritable(Adapter, SCSI) == FALSE)
			psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;

		//By Default section is Active
		psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT ;

	}


	///
	//	Control Section
	///
	if((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS)
	{
		//Setting the 0th Bit representing the Section is present or not.
		psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);


		//Setting the Access Bit. Map is not defined hece setting it always valid
		psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;

		//Checking For Access permission
		if(IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
			psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;

		//By Default section is Active
		psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT ;

	}

	///
	//	For Reserved Sections
	///
	psFlash2xBitMap->Reserved0 = 0;
	psFlash2xBitMap->Reserved0 = 0;
	psFlash2xBitMap->Reserved0 = 0;

	BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);

	return STATUS_SUCCESS ;

}
/**
BcmSetActiveSection :- Set Active section is used to make priority field highest over other
					section of same type.

@Adapater :- Bcm Driver Private Data Structure
@eFlash2xSectionVal :- Flash section val whose priority has to be made highest.

Return Value:- Make the priorit highest else return erorr code

**/
INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal)
{
	unsigned int SectImagePriority = 0;
	INT Status =STATUS_SUCCESS;

	//DSD_HEADER sDSD = {0};
	//ISO_HEADER sISO = {0};
	INT HighestPriDSD = 0 ;
	INT HighestPriISO = 0;



	Status = IsSectionWritable(Adapter,eFlash2xSectVal) ;
	if(Status != TRUE )
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section <%d> is not writable",eFlash2xSectVal);
		return STATUS_FAILURE;
	}

	Adapter->bHeaderChangeAllowed = TRUE ;
	switch(eFlash2xSectVal)
	{
		case ISO_IMAGE1 :
		case ISO_IMAGE2	:
			if(ReadISOSignature(Adapter,eFlash2xSectVal)== ISO_IMAGE_MAGIC_NUMBER )
			{
				HighestPriISO = getHighestPriISO(Adapter);

				if(HighestPriISO == eFlash2xSectVal	)
				{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already  has highest priority",eFlash2xSectVal );
					Status = STATUS_SUCCESS ;
					break;
				}

				SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;

				if((SectImagePriority <= 0) && IsSectionWritable(Adapter,HighestPriISO))
				{
					// This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
					// We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
					// by user
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
					SectImagePriority = htonl(0x1);
					Status = BcmFlash2xBulkWrite(Adapter,
								&SectImagePriority,
								HighestPriISO,
								0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
								SIGNATURE_SIZE,
								TRUE);

					if(Status)
					{
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
						Status = STATUS_FAILURE;
						break ;
					}

					HighestPriISO = getHighestPriISO(Adapter);

					if(HighestPriISO == eFlash2xSectVal	)
					{
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already  has highest priority",eFlash2xSectVal );
						Status = STATUS_SUCCESS ;
						break;
					}

					SectImagePriority = 2;
				 }


				SectImagePriority = htonl(SectImagePriority);

				Status = BcmFlash2xBulkWrite(Adapter,
								&SectImagePriority,
								eFlash2xSectVal,
								0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
								SIGNATURE_SIZE,
								TRUE);
				if(Status)
				{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
					break ;
				}
			}
			else
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
				Status = STATUS_FAILURE ;
				break;
			}
			break;
		case DSD0 :
		case DSD1 :
		case DSD2 :
			if(ReadDSDSignature(Adapter,eFlash2xSectVal)== DSD_IMAGE_MAGIC_NUMBER)
			{
				HighestPriDSD = getHighestPriDSD(Adapter);

				if((HighestPriDSD == eFlash2xSectVal))
				{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given DSD<%x> already  has highest priority", eFlash2xSectVal);
					Status = STATUS_SUCCESS ;
					break;
				}

				SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1 ;
				if(SectImagePriority <= 0)
				{
					// This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
					// We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
					// by user
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
					SectImagePriority = htonl(0x1);

					Status = BcmFlash2xBulkWrite(Adapter,
									&SectImagePriority,
									HighestPriDSD,
									Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
									SIGNATURE_SIZE,
									TRUE);

					if(Status)
					{
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
						break ;
					}

					HighestPriDSD = getHighestPriDSD(Adapter);

					if((HighestPriDSD == eFlash2xSectVal))
					{
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
						Status = STATUS_SUCCESS ;
						break;
					}

					SectImagePriority = htonl(0x2);
					Status = BcmFlash2xBulkWrite(Adapter,
									&SectImagePriority,
									HighestPriDSD,
									Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
									SIGNATURE_SIZE,
									TRUE);

					if(Status)
					{
						BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
						break ;
					}

					HighestPriDSD = getHighestPriDSD(Adapter);

					if((HighestPriDSD == eFlash2xSectVal))
					{
						Status = STATUS_SUCCESS ;
						break;
					}
					SectImagePriority = 3 ;

				}
				SectImagePriority = htonl(SectImagePriority);
				Status = BcmFlash2xBulkWrite(Adapter,
								&SectImagePriority,
								eFlash2xSectVal,
								Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
								SIGNATURE_SIZE ,
								TRUE);
				if(Status)
				{
					BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
					Status = STATUS_FAILURE ;
					break ;
				}
			}
			else
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
				Status = STATUS_FAILURE ;
				break;
			}
			break;
		case VSA0 :
		case VSA1 :
		case VSA2 :
			//Has to be decided
			break ;
		default :
				Status = STATUS_FAILURE ;
				break;

	}

	Adapter->bHeaderChangeAllowed = FALSE ;
	return Status;

}

/**
BcmCopyISO - Used only for copying the ISO section
@Adapater :- Bcm Driver Private Data Structure
@sCopySectStrut :- Section copy structure

Return value:- SUCCESS if copies successfully else negative error code

**/
INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
{

	PCHAR Buff = NULL;
	FLASH2X_SECTION_VAL eISOReadPart = 0,eISOWritePart = 0;
	UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
	UINT uiTotalDataToCopy = 0;
	BOOLEAN IsThisHeaderSector = FALSE ;
	UINT sigOffset = 0;
	UINT ISOLength = 0;
	UINT Status = STATUS_SUCCESS;
	UINT SigBuff[MAX_RW_SIZE];
	UINT i = 0;

	if(ReadISOSignature(Adapter,sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
		return STATUS_FAILURE;
	}

	Status = BcmFlash2xBulkRead(Adapter,
					   &ISOLength,
					   sCopySectStrut.SrcSection,
					   0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageSize),
					   4);

	if(Status)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
		return Status;
	}

	ISOLength = htonl(ISOLength);

	if(ISOLength % Adapter->uiSectorSize)
	{
		ISOLength = Adapter->uiSectorSize*(1 + ISOLength/Adapter->uiSectorSize);
	}

	sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);

	Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);

	if(Buff == NULL)
	{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for section size");
			return -ENOMEM;
	}

	if(sCopySectStrut.SrcSection ==ISO_IMAGE1 && sCopySectStrut.DstSection ==ISO_IMAGE2)
	{
		eISOReadPart = ISO_IMAGE1 ;
		eISOWritePart = ISO_IMAGE2 ;
		uiReadOffsetWithinPart =  0;
		uiWriteOffsetWithinPart = 0 ;

		uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);

		if(uiTotalDataToCopy < ISOLength)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
			return STATUS_FAILURE;
		}

		uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);

		if(uiTotalDataToCopy < ISOLength)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
			return STATUS_FAILURE;
		}

		uiTotalDataToCopy = ISOLength;

		CorruptISOSig(Adapter,ISO_IMAGE2);

		while(uiTotalDataToCopy)
		{
			if(uiTotalDataToCopy == Adapter->uiSectorSize)
			{
				//Setting for write of first sector. First sector is assumed to be written in last
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
				eISOReadPart = ISO_IMAGE1 ;
				uiReadOffsetWithinPart = 0;
				eISOWritePart = ISO_IMAGE2;
				uiWriteOffsetWithinPart = 0 ;
				IsThisHeaderSector = TRUE ;

			}
			else
			{
				uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
				uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;

				if((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) ))
				{
					eISOReadPart = ISO_IMAGE1_PART2 ;
					uiReadOffsetWithinPart = 0;
				}
				if((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
				{
					eISOReadPart = ISO_IMAGE1_PART3 ;
					uiReadOffsetWithinPart = 0;
				}
				if((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)))
				{
					eISOWritePart = ISO_IMAGE2_PART2 ;
					uiWriteOffsetWithinPart = 0;
				}
				if((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
				{
					eISOWritePart = ISO_IMAGE2_PART3 ;
					uiWriteOffsetWithinPart = 0;
				}
			}

			Status = BcmFlash2xBulkRead(Adapter,
								   (PUINT)Buff,
								   eISOReadPart,
								   uiReadOffsetWithinPart,
								   Adapter->uiSectorSize
								);

			if(Status)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
				break;
			}

			if(IsThisHeaderSector == TRUE)
			{
				//If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
				memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);

				for(i = 0; i < MAX_RW_SIZE;i++)
					*(Buff + sigOffset + i) = 0xFF;
			}
			Adapter->bHeaderChangeAllowed = TRUE ;

			Status = BcmFlash2xBulkWrite(Adapter,
								 (PUINT)Buff,
								 eISOWritePart,
								 uiWriteOffsetWithinPart,
								 Adapter->uiSectorSize,
								 TRUE);
			if(Status)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
				break;
			}

			Adapter->bHeaderChangeAllowed = FALSE;

			if(IsThisHeaderSector == TRUE)
			{
				WriteToFlashWithoutSectorErase(Adapter,
												SigBuff,
												eISOWritePart,
												sigOffset,
												MAX_RW_SIZE);
				IsThisHeaderSector = FALSE ;
			}
			//substracting the written Data
			uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
		}


	}

	if(sCopySectStrut.SrcSection ==ISO_IMAGE2 && sCopySectStrut.DstSection ==ISO_IMAGE1)
	{
		eISOReadPart = ISO_IMAGE2 ;
		eISOWritePart = ISO_IMAGE1 ;
		uiReadOffsetWithinPart =	0;
		uiWriteOffsetWithinPart = 0 ;

		uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);

		if(uiTotalDataToCopy < ISOLength)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
			return STATUS_FAILURE;
		}

		uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
						   (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);

		if(uiTotalDataToCopy < ISOLength)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
			return STATUS_FAILURE;
		}

		uiTotalDataToCopy = ISOLength;

		CorruptISOSig(Adapter,ISO_IMAGE1);

		while(uiTotalDataToCopy)
		{
			if(uiTotalDataToCopy == Adapter->uiSectorSize)
			{
				//Setting for write of first sector. First sector is assumed to be written in last
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
				eISOReadPart = ISO_IMAGE2 ;
				uiReadOffsetWithinPart = 0;
				eISOWritePart = ISO_IMAGE1;
				uiWriteOffsetWithinPart = 0 ;
				IsThisHeaderSector = TRUE;

			}
			else
			{
				uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
				uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;

				if((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) ))
				{
					eISOReadPart = ISO_IMAGE2_PART2 ;
					uiReadOffsetWithinPart = 0;
				}
				if((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
				{
					eISOReadPart = ISO_IMAGE2_PART3 ;
					uiReadOffsetWithinPart = 0;
				}
				if((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)))
				{
					eISOWritePart = ISO_IMAGE1_PART2 ;
					uiWriteOffsetWithinPart = 0;
				}
				if((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
				{
					eISOWritePart = ISO_IMAGE1_PART3 ;
					uiWriteOffsetWithinPart = 0;
				}
			}

			Status = BcmFlash2xBulkRead(Adapter,
								   (PUINT)Buff,
								   eISOReadPart,
								   uiReadOffsetWithinPart,
								   Adapter->uiSectorSize
								);
			if(Status)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
				break;
			}

			if(IsThisHeaderSector == TRUE)
			{
				//If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
				memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);

				for(i = 0; i < MAX_RW_SIZE;i++)
					*(Buff + sigOffset + i) = 0xFF;

			}
			Adapter->bHeaderChangeAllowed = TRUE ;
			Status = BcmFlash2xBulkWrite(Adapter,
								 (PUINT)Buff,
								 eISOWritePart,
								 uiWriteOffsetWithinPart,
								 Adapter->uiSectorSize,
								 TRUE);

			if(Status)
			{
				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
				break;
			}

			Adapter->bHeaderChangeAllowed = FALSE ;

			if(IsThisHeaderSector == TRUE)
			{
				WriteToFlashWithoutSectorErase(Adapter,
												SigBuff,
												eISOWritePart,
												sigOffset,
												MAX_RW_SIZE);
				IsThisHeaderSector = FALSE ;
			}

			//substracting the written Data
			uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
		}


	}

	kfree(Buff);

	return Status;
}
/**
BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
					     It will corrupt the sig, if Section is writable, by making first bytes as zero.
@Adapater :- Bcm Driver Private Data Structure
@eFlash2xSectionVal :- Flash section val which has header

Return Value :-
	Sucess :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
	Failure :-Return negative error code


**/
INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
{

	INT Status = STATUS_SUCCESS ;
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Section Value :%x \n", eFlash2xSectionVal);

	if((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2))
	{
		Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
	}
	else if(eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2)
	{
		Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
	}
	else
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given Section <%d>does not have Header",eFlash2xSectionVal);
		return STATUS_SUCCESS;
	}
	return Status;
}
/**
BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
					  header and  Write Permission.
@Adapater :- Bcm Driver Private Data Structure
@eFlashSectionVal :- Flash section val which has header

Return Value :-
	Sucess :- If Section is present and writable write the sig and return STATUS_SUCCESS
	Failure :-Return negative error code

**/
INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
{

	UINT uiSignature = 0 ;
	UINT uiOffset = 0;
	//DSD_HEADER dsdHeader = {0};

	if(Adapter->bSigCorrupted == FALSE)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Signature is not corrupted by driver, hence not restoring\n");
		return STATUS_SUCCESS;
	}
	if(Adapter->bAllDSDWriteAllow == FALSE)
	{
		if(IsSectionWritable(Adapter,eFlashSectionVal) == FALSE)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Write signature");
			return SECTOR_IS_NOT_WRITABLE;
		}
	}
	if((eFlashSectionVal == DSD0) ||(eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2))
	{
		uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER) ;
		uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader ;

		uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber);

		if((ReadDSDSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corrupted Pattern is not there. Hence won't write sig");
			return STATUS_FAILURE;
		}

	}
	else if((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2))
	{
		uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
		//uiOffset = 0;
		uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber);
		if((ReadISOSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Currupted Pattern is not there. Hence won't write sig");
			return STATUS_FAILURE;
		}
	}
	else
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
		return STATUS_FAILURE;
	}

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature");


	Adapter->bHeaderChangeAllowed = TRUE;
	Adapter->bSigCorrupted = FALSE;
	BcmFlash2xBulkWrite(Adapter, &uiSignature,eFlashSectionVal,uiOffset,SIGNATURE_SIZE,TRUE);
	Adapter->bHeaderChangeAllowed = FALSE;



	return STATUS_SUCCESS;
}
/**
validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
						      if requested Bytes goes beyond the Requested section, it reports error.
@Adapater :- Bcm Driver Private Data Structure
@psFlash2xReadWrite :-Flash2x Read/write structure pointer

Return values:-Return TRUE is request is valid else FALSE.


**/
INT	validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite)
{
	UINT uiNumOfBytes = 0 ;
	UINT uiSectStartOffset = 0 ;
	UINT uiSectEndOffset = 0;
	uiNumOfBytes = psFlash2xReadWrite->numOfBytes;

	if(IsSectionExistInFlash(Adapter,psFlash2xReadWrite->Section) != TRUE)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%x> does not exixt in Flash",psFlash2xReadWrite->Section);
		return FALSE;
	}
	uiSectStartOffset = BcmGetSectionValStartOffset(Adapter,psFlash2xReadWrite->Section);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n",uiSectStartOffset,psFlash2xReadWrite->Section);
	if((psFlash2xReadWrite->Section == ISO_IMAGE1) ||(psFlash2xReadWrite->Section == ISO_IMAGE2))
	{
		if(psFlash2xReadWrite->Section == ISO_IMAGE1)
		{
			uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1) -
							  BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1)+
							  BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART2) -
							  BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART2)+
							  BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART3) -
							  BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART3);
		}
		else if(psFlash2xReadWrite->Section == ISO_IMAGE2)
		{
			uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2) -
							  BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)+
							  BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART2) -
							  BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART2)+
							  BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART3) -
							  BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART3);

		}

		//since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset
		//it should be added in startoffset. so that check done in last of this function can be valued.
		uiSectEndOffset = uiSectStartOffset + uiSectEndOffset ;

		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Total size of the ISO Image :%x",uiSectEndOffset);
	}
	else
		uiSectEndOffset   = BcmGetSectionValEndOffset(Adapter,psFlash2xReadWrite->Section);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x \n",uiSectEndOffset);

	//Checking the boundary condition
	if((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
		return TRUE;
	else
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid Request....");
		return FALSE;
	}

}

/**
IsFlash2x :- check for Flash 2.x
@Adapater :- Bcm Driver Private Data Structure

Return value:-
	return TRUE if flah2.x of hgher version else return false.
**/

INT IsFlash2x(PMINI_ADAPTER Adapter)
{
	if(Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
		return TRUE ;
	else
		return FALSE;
}
/**
GetFlashBaseAddr :- Calculate the Flash Base address
@Adapater :- Bcm Driver Private Data Structure

Return Value:-
	Success :- Base Address of the Flash
**/

static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter)
{

	UINT uiBaseAddr = 0;

	if(Adapter->bDDRInitDone)
	{
		/*
		For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
		In case of Raw Read... use the default value
		*/
		if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
			!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
			)
			uiBaseAddr = Adapter->uiFlashBaseAdd ;
		else
			uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
	}
	else
	{
		/*
		For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
		In case of Raw Read... use the default value
		*/
		if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
			!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
			)
			uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
		else
			uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
	}

	return uiBaseAddr ;
}
/**
BcmCopySection :- This API is used to copy the One section in another. Both section should
				    be contiuous and of same size. Hence this Will not be applicabe to copy ISO.

@Adapater :- Bcm Driver Private Data Structure
@SrcSection :- Source section From where data has to be copied
@DstSection :- Destination section to which data has to be copied
@offset :- Offset from/to  where data has to be copied from one section to another.
@numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
			     in case of numofBytes  equal zero complete section will be copied.

Return Values-
	Sucess : Return STATUS_SUCCESS
	Faillure :- return negative error code

**/

INT	BcmCopySection(PMINI_ADAPTER Adapter,
						FLASH2X_SECTION_VAL SrcSection,
						FLASH2X_SECTION_VAL DstSection,
						UINT offset,
						UINT numOfBytes)
{
	UINT BuffSize = 0 ;
	UINT BytesToBeCopied = 0;
	PUCHAR pBuff = NULL ;
	INT Status = STATUS_SUCCESS ;
	if(SrcSection == DstSection)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source and Destination should be different ...try again");
		return -EINVAL;
	}
	if((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2))
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source should be DSD subsection");
		return  -EINVAL;
	}
	if((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2))
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destination should be DSD subsection");
		return  -EINVAL;
	}

	//if offset zero means have to copy complete secton

	if(numOfBytes == 0)
	{
		numOfBytes = BcmGetSectionValEndOffset(Adapter,SrcSection)
				  - BcmGetSectionValStartOffset(Adapter,SrcSection);

		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Section Size :0x%x",numOfBytes);
	}

	if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,SrcSection)
				  - BcmGetSectionValStartOffset(Adapter,SrcSection))
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
						offset, numOfBytes);
		return -EINVAL;
	}

	if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,DstSection)
				  - BcmGetSectionValStartOffset(Adapter,DstSection))
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
						offset, numOfBytes);
		return -EINVAL;
	}


	if(numOfBytes > Adapter->uiSectorSize )
		BuffSize = Adapter->uiSectorSize;
	else
		BuffSize = numOfBytes ;

	pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL);
	if(pBuff == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed.. ");
		return -ENOMEM;
	}


	BytesToBeCopied = Adapter->uiSectorSize ;
	if(offset % Adapter->uiSectorSize)
		BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
	if(BytesToBeCopied > numOfBytes)
		BytesToBeCopied = numOfBytes ;



	Adapter->bHeaderChangeAllowed = TRUE;

	do
	{
		Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset,BytesToBeCopied);
		if(Status)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection,BytesToBeCopied);
			break;
		}
		Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pBuff,DstSection,offset,BytesToBeCopied,FALSE);
		if(Status)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection,BytesToBeCopied);
			break;
		}
		offset = offset + BytesToBeCopied;
		numOfBytes = numOfBytes - BytesToBeCopied ;
		if(numOfBytes)
		{
			if(numOfBytes > Adapter->uiSectorSize )
				BytesToBeCopied = Adapter->uiSectorSize;
			else
				BytesToBeCopied = numOfBytes;
		}
	}while(numOfBytes > 0) ;
	kfree(pBuff);
	Adapter->bHeaderChangeAllowed = FALSE ;
	return Status;
}

/**
SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
@Adapater :- Bcm Driver Private Data Structure
@pBuff :- Data buffer that has to be written in sector having the header map.
@uiOffset :- Flash offset that has to be written.

Return value :-
	Sucess :- On sucess return STATUS_SUCCESS
	Faillure :- Return negative error code

**/

INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset)
{
	UINT offsetToProtect = 0,HeaderSizeToProtect =0;
	BOOLEAN bHasHeader = FALSE ;
	PUCHAR pTempBuff =NULL;
	UINT uiSectAlignAddr = 0;
	UINT sig = 0;

	//making the offset sector alligned
	uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);


	if((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD2)- Adapter->uiSectorSize)||
	(uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD1)- Adapter->uiSectorSize)||
	(uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD0)- Adapter->uiSectorSize))
	{

		//offset from the sector boundry having the header map
		offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
		HeaderSizeToProtect = sizeof(DSD_HEADER);
		bHasHeader = TRUE ;
	}

	if(uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1) ||
		uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2))
	{
		offsetToProtect = 0;
		HeaderSizeToProtect = sizeof(ISO_HEADER);
		bHasHeader = TRUE;
	}
	//If Header is present overwrite passed buffer with this
	if(bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE))
	{
		pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL);
		if(pTempBuff == NULL)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed ");
			return -ENOMEM;
		}
		//Read header
		BeceemFlashBulkRead(Adapter,(PUINT)pTempBuff,(uiSectAlignAddr + offsetToProtect),HeaderSizeToProtect);
		BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pTempBuff ,HeaderSizeToProtect);
		//Replace Buffer content with Header
		memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect);

		kfree(pTempBuff);
	}
	if(bHasHeader && Adapter->bSigCorrupted)
	{
		sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)));
		sig = ntohl(sig);
		if((sig & 0xFF000000) != CORRUPTED_PATTERN)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Desired pattern is not at sig offset. Hence won't restore");
			Adapter->bSigCorrupted = FALSE;
			return STATUS_SUCCESS;
		}
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Corrupted sig is :%X", sig);
		*((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber)))= htonl(DSD_IMAGE_MAGIC_NUMBER);
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature in Header Write only");
		Adapter->bSigCorrupted = FALSE;
	}

	return STATUS_SUCCESS ;
}

/**
BcmDoChipSelect : This will selcet the appropriate chip for writing.
@Adapater :- Bcm Driver Private Data Structure

OutPut:-
	Select the Appropriate chip and retrn status Sucess
**/
static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset)
{
	UINT FlashConfig = 0;
	INT ChipNum = 0;
	UINT GPIOConfig = 0;
	UINT PartNum = 0;

	ChipNum = offset / FLASH_PART_SIZE ;

	//
	// Chip Select mapping to enable flash0.
	// To select flash 0, we have to OR with (0<<12).
	// ORing 0 will have no impact so not doing that part.
	// In future if Chip select value changes from 0 to non zero,
	// That needs be taken care with backward comaptibility. No worries for now.
	//

	/*
	SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
	if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
	Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
	power down modes (Idle mode/shutdown mode), the values in the register will be different.
	*/

	if(Adapter->SelectedChip == ChipNum)
    		return STATUS_SUCCESS;

	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum);
	Adapter->SelectedChip = ChipNum ;

	//bit[13..12]  will select the appropriate chip
	rdmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
	rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);

	{
		switch(ChipNum)
		{
		case 0:
			PartNum = 0;
			break;
		case 1:
			PartNum = 3;
			GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
			break;
		case 2:
			PartNum = 1;
			GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
			break;
		case 3:
			PartNum = 2;
			GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
			break;
		}
	}
	/* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
	    nothing to do... can return immediately.
	    ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
	    Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
	    These values are not written by host other than during CHIP_SELECT.
	*/
	if(PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
		return STATUS_SUCCESS;

	//clearing the bit[13..12]
	FlashConfig &= 0xFFFFCFFF;
	FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); //00

	wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
	udelay(100);

	wrmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
	udelay(100);

	return STATUS_SUCCESS;

}
INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
{
		UINT uiDSDsig = 0;
		//UINT sigoffsetInMap = 0;
		//DSD_HEADER dsdHeader = {0};


		//sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader;

		if(dsd != DSD0 && dsd != DSD1 && dsd != DSD2)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for DSDs");
			return STATUS_FAILURE;
		}
		BcmFlash2xBulkRead(Adapter,
						   &uiDSDsig,
						   dsd,
						   Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber),
						   SIGNATURE_SIZE);

		uiDSDsig = ntohl(uiDSDsig);
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD SIG :%x", uiDSDsig);

		return uiDSDsig ;
}
INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
{
	//UINT priOffsetInMap = 0 ;
	unsigned int uiDSDPri = STATUS_FAILURE;
	//DSD_HEADER dsdHeader = {0};
	//priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
	if(IsSectionWritable(Adapter,dsd))
	{
		if(ReadDSDSignature(Adapter,dsd)== DSD_IMAGE_MAGIC_NUMBER)
		{
			BcmFlash2xBulkRead(Adapter,
							   &uiDSDPri,
							   dsd,
							   Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader +FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
							   4);

			uiDSDPri = ntohl(uiDSDPri);
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD<%x> Priority :%x", dsd, uiDSDPri);

		}
	}
	return uiDSDPri;
}
FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter)
{
	INT DSDHighestPri = STATUS_FAILURE;
	INT  DsdPri= 0 ;
	FLASH2X_SECTION_VAL HighestPriDSD = 0 ;

	if(IsSectionWritable(Adapter,DSD2))
	{
		DSDHighestPri = ReadDSDPriority(Adapter,DSD2);
		HighestPriDSD = DSD2 ;
	}
	if(IsSectionWritable(Adapter,DSD1))
	{
		 DsdPri = ReadDSDPriority(Adapter,DSD1);
		 if(DSDHighestPri  < DsdPri)
		 {
		 	DSDHighestPri = DsdPri ;
			HighestPriDSD = DSD1;
		 }
	}
	if(IsSectionWritable(Adapter,DSD0))
	{
		 DsdPri = ReadDSDPriority(Adapter,DSD0);
		 if(DSDHighestPri  < DsdPri)
		 {
		 	DSDHighestPri = DsdPri ;
			HighestPriDSD = DSD0;
		 }
	}
	if(HighestPriDSD)
	 	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest DSD :%x , and its  Pri :%x", HighestPriDSD, DSDHighestPri);
	return  HighestPriDSD ;
}

INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
{
		UINT uiISOsig = 0;
		//UINT sigoffsetInMap = 0;
		//ISO_HEADER ISOHeader = {0};


		//sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;

		if(iso != ISO_IMAGE1 && iso != ISO_IMAGE2)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for ISOs");
			return STATUS_FAILURE;
		}
		BcmFlash2xBulkRead(Adapter,
						   &uiISOsig,
						   iso,
						   0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber),
						   SIGNATURE_SIZE);

		uiISOsig = ntohl(uiISOsig);
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO SIG :%x", uiISOsig);

		return uiISOsig ;
}
INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
{

	unsigned int ISOPri = STATUS_FAILURE;
	if(IsSectionWritable(Adapter,iso))
	{
		if(ReadISOSignature(Adapter,iso)== ISO_IMAGE_MAGIC_NUMBER)
		{
			BcmFlash2xBulkRead(Adapter,
							   &ISOPri,
							   iso,
							   0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
							   4);

			ISOPri = ntohl(ISOPri);
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO<%x> Priority :%x", iso, ISOPri);

		}
	}
	return ISOPri;
}
FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter)
{
	INT ISOHighestPri = STATUS_FAILURE;
	INT  ISOPri= 0 ;
	FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL ;

	if(IsSectionWritable(Adapter,ISO_IMAGE2))
	{
		ISOHighestPri = ReadISOPriority(Adapter,ISO_IMAGE2);
		HighestPriISO = ISO_IMAGE2 ;
	}
	if(IsSectionWritable(Adapter,ISO_IMAGE1))
	{
		 ISOPri = ReadISOPriority(Adapter,ISO_IMAGE1);
		 if(ISOHighestPri  < ISOPri)
		 {
			ISOHighestPri = ISOPri ;
			HighestPriISO = ISO_IMAGE1;
		 }
	}
	if(HighestPriISO)
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest ISO :%x and its Pri :%x",HighestPriISO,ISOHighestPri);
	return	HighestPriISO ;
}
INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
										PUINT pBuff,
										FLASH2X_SECTION_VAL eFlash2xSectionVal,
										UINT uiOffset,
										UINT uiNumBytes
										)
{
#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
	UINT uiTemp = 0, value = 0 ;
	UINT i = 0;
	UINT uiPartOffset = 0;
#endif
	UINT uiStartOffset = 0;
	//Adding section start address
	INT Status = STATUS_SUCCESS;
	PUCHAR pcBuff = (PUCHAR)pBuff;

	if(uiNumBytes % Adapter->ulFlashWriteSize)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
		return STATUS_FAILURE;
	}

	uiStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);

	if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
	{
		return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
	}

	uiOffset = uiOffset + uiStartOffset;

#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
  Status = bcmflash_raw_writenoerase((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE), pcBuff,uiNumBytes);
#else
	rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
	value = 0;
	wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));

	Adapter->SelectedChip = RESET_CHIP_SELECT;
	BcmDoChipSelect(Adapter,uiOffset);
	uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);

	for(i = 0 ; i< uiNumBytes; i += Adapter->ulFlashWriteSize)
	{
		if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
			Status = flashByteWrite(Adapter,uiPartOffset, pcBuff);
		else
			Status = flashWrite(Adapter,uiPartOffset, pcBuff);

		if(Status != STATUS_SUCCESS)
			break;

		pcBuff = pcBuff + Adapter->ulFlashWriteSize;
		uiPartOffset = uiPartOffset +  Adapter->ulFlashWriteSize;
	}
	wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
	Adapter->SelectedChip = RESET_CHIP_SELECT;
#endif

	return Status;
}

BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
{

	BOOLEAN SectionPresent = FALSE ;

	switch(section)
	{

		case ISO_IMAGE1 :
			  if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
			  		(IsNonCDLessDevice(Adapter) == FALSE))
				  SectionPresent = TRUE ;
			   break;
		case ISO_IMAGE2 :
				if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
					(IsNonCDLessDevice(Adapter) == FALSE))
					 SectionPresent = TRUE ;
			  break;
		case DSD0 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
					 SectionPresent = TRUE ;
				break;
		case DSD1 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
					 SectionPresent = TRUE ;
				break;
		case DSD2 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
					 SectionPresent = TRUE ;
				break;
		case VSA0 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
					 SectionPresent = TRUE ;
				break;
		case VSA1 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
					 SectionPresent = TRUE ;
				break;
		case VSA2 :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
					 SectionPresent = TRUE ;
				break;
		case SCSI :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
					 SectionPresent = TRUE ;
				break;
		case CONTROL_SECTION :
				if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
					 SectionPresent = TRUE ;
				break;
		default :
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
			SectionPresent =  FALSE;
	}
	return SectionPresent ;
}
INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section)
{
		INT offset = STATUS_FAILURE;
		INT Status = FALSE;
		if(IsSectionExistInFlash(Adapter,Section) == FALSE)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section <%d> does not exixt", Section);
			return FALSE;
		}
		offset = BcmGetSectionValStartOffset(Adapter,Section);
		if(offset == INVALID_OFFSET)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%d> does not exixt", Section);
			return FALSE;
		}

		if(IsSectionExistInVendorInfo(Adapter,Section))
		{
			return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
		}

		Status = IsOffsetWritable(Adapter,offset);
		return Status ;
}

static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
{

	PUCHAR pBuff = NULL;
	UINT sig = 0;
	UINT uiOffset = 0;
	UINT BlockStatus = 0;
	UINT uiSectAlignAddr = 0;

	Adapter->bSigCorrupted = FALSE;

	if(Adapter->bAllDSDWriteAllow == FALSE)
	{
		if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
		{
			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
			return SECTOR_IS_NOT_WRITABLE;
		}
	}

	pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
	if(pBuff == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
		return -ENOMEM ;
	}

	uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER);
	uiOffset -= MAX_RW_SIZE ;

	BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset,MAX_RW_SIZE);


	sig = *((PUINT)(pBuff +12));
	sig =ntohl(sig);
	BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
	//Now corrupting the sig by corrupting 4th last Byte.
	*(pBuff + 12) = 0;

	if(sig == DSD_IMAGE_MAGIC_NUMBER)
	{
		Adapter->bSigCorrupted = TRUE;
		if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
		{
			uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize -1);
			BlockStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);

			WriteToFlashWithoutSectorErase(Adapter,(PUINT)(pBuff + 12),eFlash2xSectionVal,
												(uiOffset + 12),BYTE_WRITE_SUPPORT);
			if(BlockStatus)
			{
				BcmRestoreBlockProtectStatus(Adapter,BlockStatus);
				BlockStatus = 0;
			}
		}
		else
		{
			WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
												uiOffset ,MAX_RW_SIZE);
		}
	}
	else
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
		kfree(pBuff);
		return STATUS_FAILURE;
	}

	kfree(pBuff);
	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
	return STATUS_SUCCESS ;
}

static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
{

	PUCHAR pBuff = NULL;
	UINT sig = 0;
	UINT uiOffset = 0;

	Adapter->bSigCorrupted = FALSE;

	if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
		return SECTOR_IS_NOT_WRITABLE;
	}

	pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
	if(pBuff == NULL)
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allocate memorey");
		return -ENOMEM ;
	}

	uiOffset = 0;

	BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset, MAX_RW_SIZE);

	sig = *((PUINT)pBuff);
	sig =ntohl(sig);

	//corrupt signature
	*pBuff = 0;

	if(sig == ISO_IMAGE_MAGIC_NUMBER)
	{
		Adapter->bSigCorrupted = TRUE;
		WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
											uiOffset ,Adapter->ulFlashWriteSize);
	}
	else
	{
		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
		kfree(pBuff);
		return STATUS_FAILURE;
	}

	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
	BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);

	kfree(pBuff);
	return STATUS_SUCCESS ;
}

BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter)
{
	if(Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
		return TRUE;
	else
		return FALSE ;
}

