#include "headers.h"

#define DWORD unsigned int

static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset);
static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter);
static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter);
static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter);
static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter);
static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize);

static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter);
static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter);
static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter);
static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter);

static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);

static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset);
static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section);
static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);

static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);
static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);

static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiSectAlignAddr);
static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff,
					enum bcm_flash2x_section_val eFlash2xSectionVal,
					unsigned int uiOffset, unsigned int uiNumBytes);
static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter);
static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter);

static int BeceemFlashBulkRead(
	struct bcm_mini_adapter *Adapter,
	PUINT pBuffer,
	unsigned int uiOffset,
	unsigned int uiNumBytes);

static int BeceemFlashBulkWrite(
	struct bcm_mini_adapter *Adapter,
	PUINT pBuffer,
	unsigned int uiOffset,
	unsigned int uiNumBytes,
	BOOLEAN bVerify);

static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter);

static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, unsigned int dwAddress, unsigned int *pdwData, unsigned int dwNumData);

/* Procedure:	ReadEEPROMStatusRegister
 *
 * Description: Reads the standard EEPROM Status Register.
 *
 * Arguments:
 *		Adapter    - ptr to Adapter object instance
 * Returns:
 *		OSAL_STATUS_CODE
 */
static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter)
{
	UCHAR uiData = 0;
	DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
	unsigned int uiStatus = 0;
	unsigned int value = 0;
	unsigned int 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))
			udelay(1000);
		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(struct bcm_mini_adapter *Adapter,
			DWORD dwAddress,
			DWORD *pdwData,
			DWORD dwNumWords)
{
	DWORD dwIndex = 0;
	DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
	unsigned int uiStatus  = 0;
	unsigned int value = 0;
	unsigned int 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))
			udelay(1000);
	}

	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(struct bcm_mini_adapter *Adapter,
		DWORD uiOffset,
		DWORD *pBuffer)
{
	unsigned int uiData[8]		= {0};
	unsigned int uiByteOffset	= 0;
	unsigned int 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(struct bcm_mini_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 successful.
 *		<FAILURE>			- if failed.
 */

int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter,
			PUINT pBuffer,
			unsigned int uiOffset,
			unsigned int uiNumBytes)
{
	unsigned int uiData[4]		= {0};
	/* unsigned int uiAddress	= 0; */
	unsigned int uiBytesRemaining	= uiNumBytes;
	unsigned int uiIndex		= 0;
	unsigned int uiTempOffset	= 0;
	unsigned int uiExtraBytes	= 0;
	unsigned int 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 (ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4) == 0) {
				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 (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 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 (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 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 successful.
 *		<FAILURE>			- if failed.
 */

static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter,
			PUINT pBuffer,
			unsigned int uiOffset,
			unsigned int uiNumBytes)
{
	unsigned int uiIndex = 0;
	unsigned int uiBytesToRead = uiNumBytes;
	int Status = 0;
	unsigned int uiPartOffset = 0;
	int bytes;

	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);

		bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
		if (bytes < 0) {
			Status = bytes;
			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);

		bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
		if (bytes < 0) {
			Status = bytes;
			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:
 *		unsigned int - size of the FLASH Storage.
 *
 */

static unsigned int BcmGetFlashSize(struct bcm_mini_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:
 *		unsigned int - size of the EEPROM Storage.
 *
 */

static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter)
{
	unsigned int uiData = 0;
	unsigned int 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 (BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE) == 0) {
			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(struct bcm_mini_adapter *Adapter,
			unsigned int addr,
			unsigned int numOfSectors)
{
	unsigned int iIndex = 0, iRetries = 0;
	unsigned int uiStatus = 0;
	unsigned int value;
	int bytes;

	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;
			}

			bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
			if (bytes < 0) {
				uiStatus = bytes;
				BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
				return uiStatus;
			}
			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.
			 */
			mdelay(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(struct bcm_mini_adapter *Adapter,
			unsigned int uiOffset,
			PVOID pData)
{
	unsigned int uiStatus = 0;
	int  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
	unsigned int value;
	ULONG ulData = *(PUCHAR)pData;
	int bytes;
	/*
	 * 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); */
		bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
		if (bytes < 0) {
			uiStatus = bytes;
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
			return uiStatus;
		}
		iRetries--;
		if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
			udelay(1000);

	} 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(struct bcm_mini_adapter *Adapter,
		unsigned int uiOffset,
		PVOID pData)
{
	/* unsigned int uiStatus = 0;
	 * int  iRetries = 0;
	 * unsigned int uiReadBack = 0;
	 */
	unsigned int uiStatus = 0;
	int  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
	unsigned int value;
	unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
	int bytes;
	/*
	 * 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); */
		bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
		if (bytes < 0) {
			uiStatus = bytes;
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
			return uiStatus;
		}

		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))
			udelay(1000);
	} 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(struct bcm_mini_adapter *Adapter,
				unsigned int uiOffset,
				PVOID pData)
{
	unsigned int uiStatus = 0;
	int  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
	ULONG ulData  = *(PUCHAR)pData;
	unsigned int value;
	int bytes;

	/*
	 * 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); */
		bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
		if (bytes < 0) {
			uiStatus = bytes;
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
			return uiStatus;
		}

		iRetries--;
		if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
			udelay(1000);

	} 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(struct bcm_mini_adapter *Adapter,
			unsigned int uiOffset,
			PVOID pData)
{
	unsigned int uiStatus = 0;
	int  iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
	/* unsigned int uiReadBack = 0; */
	unsigned int value;
	unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
	int bytes;

	/*
	 * 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); */
		bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
		if (bytes < 0) {
			uiStatus = bytes;
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
			return uiStatus;
		}
		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))
			udelay(1000);

	} 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(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus)
{
	unsigned int 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(struct bcm_mini_adapter *Adapter, unsigned int uiOffset, unsigned int uiLength)
{
	ULONG ulStatus		= 0;
	ULONG ulWriteStatus	= 0;
	unsigned int 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(struct bcm_mini_adapter *Adapter,
				PUINT pBuffer,
				unsigned int uiOffset,
				unsigned int uiNumBytes,
				BOOLEAN bVerify)
{
	PCHAR pTempBuff			= NULL;
	PUCHAR pcBuffer			= (PUCHAR)pBuffer;
	unsigned int uiIndex			= 0;
	unsigned int uiOffsetFromSectStart	= 0;
	unsigned int uiSectAlignAddr		= 0;
	unsigned int uiCurrSectOffsetAddr	= 0;
	unsigned int uiSectBoundary		= 0;
	unsigned int uiNumSectTobeRead		= 0;
	UCHAR ucReadBk[16]		= {0};
	ULONG ulStatus			= 0;
	int Status			= STATUS_SUCCESS;
	unsigned int uiTemp			= 0;
	unsigned int index			= 0;
	unsigned int 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 (!pTempBuff)
		goto BeceemFlashBulkWrite_EXIT;
	/*
	 * check if the data to be written is overlapped across 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) {
					unsigned int 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(struct bcm_mini_adapter *Adapter,
				PUINT pBuffer,
				unsigned int uiOffset,
				unsigned int uiNumBytes,
				BOOLEAN bVerify)
{
	PCHAR pTempBuff			= NULL;
	PUCHAR pcBuffer			= (PUCHAR)pBuffer;
	unsigned int uiIndex			= 0;
	unsigned int uiOffsetFromSectStart	= 0;
	unsigned int uiSectAlignAddr		= 0;
	unsigned int uiCurrSectOffsetAddr	= 0;
	unsigned int uiSectBoundary		= 0;
	unsigned int uiNumSectTobeRead		= 0;
	UCHAR ucReadBk[16]		= {0};
	ULONG ulStatus			= 0;
	unsigned int Status			= STATUS_SUCCESS;
	unsigned int uiTemp			= 0;
	unsigned int index			= 0;
	unsigned int 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 (!pTempBuff)
		goto BeceemFlashBulkWriteStatus_EXIT;

	/*
	 * check if the data to be written is overlapped across 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(struct bcm_mini_adapter *Adapter)
{
	PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL);
	unsigned int uiEepromSize = 0;
	unsigned int uiIndex = 0;
	unsigned int uiBytesToCopy = 0;
	unsigned int uiCalStartAddr = EEPROM_CALPARAM_START;
	unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
	unsigned int value;
	int Status = 0;

	if (!pBuff)
		return -ENOMEM;

	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(struct bcm_mini_adapter *Adapter)
{
	PCHAR pBuff, pPtr;
	unsigned int uiEepromSize = 0;
	unsigned int uiBytesToCopy = 0;
	/* unsigned int uiIndex = 0; */
	unsigned int uiCalStartAddr = EEPROM_CALPARAM_START;
	unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
	unsigned int 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 -ENOMEM;

	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(struct bcm_mini_adapter *Adapter,
					PUINT pBuffer,
					unsigned int uiOffset,
					unsigned int uiNumBytes)
{
	unsigned int uiRdbk	= 0;
	unsigned int uiIndex	= 0;
	unsigned int uiData	= 0;
	unsigned int 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(unsigned int)), uiNumBytes);
			BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4);

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

			uiNumBytes = 0;
		}
	}

	return 0;
}

static VOID BcmSwapWord(unsigned int *ptr1)
{
	unsigned int tempval = (unsigned int)*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(struct bcm_mini_adapter *Adapter, unsigned int uiData[], unsigned int uiOffset)
{
	unsigned int uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
	unsigned int uiStatus = 0;
	UCHAR uiEpromStatus = 0;
	unsigned int 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))
			udelay(1000);

		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))
			udelay(1000);
	}

	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(struct bcm_mini_adapter *Adapter,
			PUCHAR pBuffer,
			unsigned int uiOffset,
			unsigned int uiNumBytes,
			BOOLEAN bVerify)
{
	unsigned int uiBytesToCopy	= uiNumBytes;
	/* unsigned int uiRdbk		= 0; */
	unsigned int uiData[4]		= {0};
	unsigned int uiIndex		= 0;
	unsigned int uiTempOffset	= 0;
	unsigned int 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 successful.
 *		<FAILURE>			- if failed.
 */

int BeceemNVMRead(struct bcm_mini_adapter *Adapter,
		PUINT pBuffer,
		unsigned int uiOffset,
		unsigned int uiNumBytes)
{
	int Status = 0;

	#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
		unsigned int 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 successful.
 *		<FAILURE>			- if failed.
 */

int BeceemNVMWrite(struct bcm_mini_adapter *Adapter,
		PUINT pBuffer,
		unsigned int uiOffset,
		unsigned int uiNumBytes,
		BOOLEAN bVerify)
{
	int Status = 0;
	unsigned int uiTemp = 0;
	unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
	unsigned int uiIndex = 0;

	#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
		unsigned int value;
	#endif

	unsigned int 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 successful.
 *		<FAILURE>			- if failed.
 */

int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, unsigned int uiSectorSize)
{
	int Status = -1;
	FLASH_CS_INFO sFlashCsInfo = {0};
	unsigned int uiTemp = 0;
	unsigned int uiSectorSig = 0;
	unsigned int uiCurrentSectorSize = 0;
	unsigned int 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:
 *		unsigned int - sector size.
 *
 */

static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize)
{
	unsigned int uiSectorSize = 0;
	unsigned int 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;
			} else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
				Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) {
				/* No valid size in FLASH, check if Config file has it. */
				Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
			} else {
				/* Init to Default, if none of the above works. */
				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(struct bcm_mini_adapter *Adapter)
{
	unsigned int 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(struct bcm_mini_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 success;
 */

static int BcmGetNvmSize(struct bcm_mini_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(struct bcm_mini_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(struct bcm_mini_adapter *Adapter)
{
	ULONG ulRDID = 0;
	unsigned int 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(struct bcm_mini_adapter *psAdapter)
{
	if (!psAdapter) {
		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) {
		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) {
		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(struct bcm_mini_adapter *psAdapter)
{
	if (!psAdapter) {
		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, struct bcm_mini_adapter *Adapter)
{
	unsigned int 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)
{
	unsigned int 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)
{
	/* unsigned int 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(struct bcm_mini_adapter *Adapter, enum bcm_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(struct bcm_mini_adapter *Adapter)
{
	B_UINT32 i = 0;
	unsigned int 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(struct bcm_mini_adapter *Adapter)
{
	/* FLASH_CS_INFO sFlashCsInfo = {0}; */

	#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
		unsigned int value;
	#endif

	unsigned int 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(struct bcm_mini_adapter *Adapter)
{
	unsigned int 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 bcm_flash2x_section_val
 *
 * Return value:-
 * On success it return the start offset of the provided section val
 * On Failure -returns STATUS_FAILURE
 */

int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_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 Structure.
	 */

	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 bcm_flash2x_section_val
 *
 * Return value:-
 * On success it return the end offset of the provided section val
 * On Failure -returns STATUS_FAILURE
 */

int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_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 enum bcm_flash2x_section_val
 * @uiOffsetWithinSectionVal :- Offset with in provided section
 * @uiNumBytes : Number of Bytes for Read
 *
 * Return value:-
 * return true on success and STATUS_FAILURE on fail.
 */

int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
		PUINT pBuffer,
		enum bcm_flash2x_section_val eFlash2xSectionVal,
		unsigned int uiOffsetWithinSectionVal,
		unsigned int uiNumBytes)
{
	int Status = STATUS_SUCCESS;
	int SectionStartOffset = 0;
	unsigned int uiAbsoluteOffset = 0;
	unsigned int uiTemp = 0, value = 0;

	if (!Adapter) {
		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 enum bcm_flash2x_section_val
 * @uiOffsetWithinSectionVal :- Offset with in provided section
 * @uiNumBytes : Number of Bytes for Write
 *
 * Return value:-
 * return true on success and STATUS_FAILURE on fail.
 *
 */

int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
			PUINT pBuffer,
			enum bcm_flash2x_section_val eFlash2xSectVal,
			unsigned int uiOffset,
			unsigned int uiNumBytes,
			unsigned int bVerify)
{
	int Status = STATUS_SUCCESS;
	unsigned int FlashSectValStartOffset = 0;
	unsigned int uiTemp = 0, value = 0;

	if (!Adapter) {
		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 success in setting the right DSD else negaive error code
 *
 */

static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter)
{
	enum bcm_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(struct bcm_mini_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:-
 * Success:-TRUE ,  offset is writable
 * Failure:-FALSE, offset is RO
 *
 */

B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset)
{
	unsigned int uiSectorNum = 0;
	unsigned int uiWordOfSectorPermission = 0;
	unsigned int 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(struct bcm_flash2x_bitmap *psFlash2xBitMap)
{
	struct bcm_mini_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:-
 * Success:- STATUS_SUCESS
 * Failure:- negative error code
 */

int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap)
{
	PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
	enum bcm_flash2x_section_val uiHighestPriDSD = 0;
	enum bcm_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(struct bcm_mini_adapter *Adapter, enum bcm_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 happened, 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 happened, 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(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut)
{
	PCHAR Buff = NULL;
	enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0;
	unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
	unsigned int uiTotalDataToCopy = 0;
	BOOLEAN IsThisHeaderSector = FALSE;
	unsigned int sigOffset = 0;
	unsigned int ISOLength = 0;
	unsigned int Status = STATUS_SUCCESS;
	unsigned int SigBuff[MAX_RW_SIZE];
	unsigned int 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) {
		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");
			Status = STATUS_FAILURE;
			goto out;
		}

		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");
			Status = STATUS_FAILURE;
			goto out;
		}

		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;
			}
			/* subtracting 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");
			Status = STATUS_FAILURE;
			goto out;
		}

		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");
			Status = STATUS_FAILURE;
			goto out;
		}

		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;
			}

			/* subtracting the written Data */
			uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
		}
	}
out:
	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 :-
 *	Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
 *	Failure :-Return negative error code
 */

int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_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 :-
 *	Success :- If Section is present and writable write the sig and return STATUS_SUCCESS
 *	Failure :-Return negative error code
 */

int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
{
	unsigned int uiSignature = 0;
	unsigned int 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(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite)
{
	unsigned int uiNumOfBytes = 0;
	unsigned int uiSectStartOffset = 0;
	unsigned int 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 virtual 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(struct bcm_mini_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(struct bcm_mini_adapter *Adapter)
{
	unsigned int 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-
 *	Success : Return STATUS_SUCCESS
 *	Faillure :- return negative error code
 */

int BcmCopySection(struct bcm_mini_adapter *Adapter,
		enum bcm_flash2x_section_val SrcSection,
		enum bcm_flash2x_section_val DstSection,
		unsigned int offset,
		unsigned int numOfBytes)
{
	unsigned int BuffSize = 0;
	unsigned int 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) {
		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 :-
 *	Success :- On success return STATUS_SUCCESS
 *	Faillure :- Return negative error code
 */

int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset)
{
	unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0;
	BOOLEAN bHasHeader = FALSE;
	PUCHAR pTempBuff = NULL;
	unsigned int uiSectAlignAddr = 0;
	unsigned int sig = 0;

	/* making the offset sector aligned */
	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 boundary 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) {
			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 Success
 */
static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset)
{
	unsigned int FlashConfig = 0;
	int ChipNum = 0;
	unsigned int GPIOConfig = 0;
	unsigned int 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(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
{
	unsigned int uiDSDsig = 0;
	/* unsigned int 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(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
{
	/* unsigned int 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;
}

enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
{
	int DSDHighestPri = STATUS_FAILURE;
	int DsdPri = 0;
	enum bcm_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(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
{
	unsigned int uiISOsig = 0;
	/* unsigned int 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(struct bcm_mini_adapter *Adapter, enum bcm_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;
}

enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
{
	int ISOHighestPri = STATUS_FAILURE;
	int ISOPri = 0;
	enum bcm_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(struct bcm_mini_adapter *Adapter,
				PUINT pBuff,
				enum bcm_flash2x_section_val eFlash2xSectionVal,
				unsigned int uiOffset,
				unsigned int uiNumBytes)
{
	#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
		unsigned int uiTemp = 0, value = 0;
		unsigned int i = 0;
		unsigned int uiPartOffset = 0;
	#endif
	unsigned int 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(struct bcm_mini_adapter *Adapter, enum bcm_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(struct bcm_mini_adapter *Adapter, enum bcm_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(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
	PUCHAR pBuff = NULL;
	unsigned int sig = 0;
	unsigned int uiOffset = 0;
	unsigned int BlockStatus = 0;
	unsigned int 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 can't Corrupt signature");
			return SECTOR_IS_NOT_WRITABLE;
		}
	}

	pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
	if (!pBuff) {
		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(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
{
	PUCHAR pBuff = NULL;
	unsigned int sig = 0;
	unsigned int uiOffset = 0;

	Adapter->bSigCorrupted = FALSE;

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

	pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
	if (!pBuff) {
		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(struct bcm_mini_adapter *Adapter)
{
	if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
		return TRUE;
	else
		return FALSE;
}
