summaryrefslogtreecommitdiffstats
path: root/drivers/staging/bcm/nvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/bcm/nvm.c')
-rw-r--r--drivers/staging/bcm/nvm.c5614
1 files changed, 5614 insertions, 0 deletions
diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c
new file mode 100644
index 0000000..41c9ab8
--- /dev/null
+++ b/drivers/staging/bcm/nvm.c
@@ -0,0 +1,5614 @@
+#include "headers.h"
+
+#define DWORD unsigned int
+// Procedure: ReadEEPROMStatusRegister
+//
+// Description: Reads the standard EEPROM Status Register.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+static UCHAR ReadEEPROMStatusRegister( PMINI_ADAPTER Adapter )
+{
+ UCHAR uiData = 0;
+ DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
+ UINT uiStatus = 0;
+ UINT value = 0;
+ UINT value1 = 0;
+
+ /* Read the EEPROM status register */
+ value = EEPROM_READ_STATUS_REGISTER ;
+ wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
+
+ while ( dwRetries != 0 )
+ {
+ value=0;
+ uiStatus = 0 ;
+ rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus));
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got removed hence exiting....");
+ break;
+ }
+
+ /* Wait for Avail bit to be set. */
+ if ( ( uiStatus & EEPROM_READ_DATA_AVAIL) != 0 )
+ {
+ /* Clear the Avail/Full bits - which ever is set. */
+ value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+
+ value =0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+ uiData = (UCHAR)value;
+
+ break;
+ }
+
+ dwRetries-- ;
+ if ( dwRetries == 0 )
+ {
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"0x3004 = %x 0x3008 = %x, retries = %d failed.\n",value,value1, MAX_EEPROM_RETRIES*RETRIES_PER_DELAY);
+ return uiData;
+ }
+ if( !(dwRetries%RETRIES_PER_DELAY) )
+ msleep(1);
+ uiStatus = 0 ;
+ }
+ return uiData;
+} /* ReadEEPROMStatusRegister */
+
+//-----------------------------------------------------------------------------
+// Procedure: ReadBeceemEEPROMBulk
+//
+// Description: This routine reads 16Byte data from EEPROM
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// dwAddress - EEPROM Offset to read the data from.
+// pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY.
+//
+// Returns:
+// OSAL_STATUS_CODE:
+//-----------------------------------------------------------------------------
+
+INT ReadBeceemEEPROMBulk( PMINI_ADAPTER Adapter,
+ DWORD dwAddress,
+ DWORD *pdwData,
+ DWORD dwNumWords
+ )
+{
+ DWORD dwIndex = 0;
+ DWORD dwRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
+ UINT uiStatus = 0;
+ UINT value= 0;
+ UINT value1 = 0;
+ UCHAR *pvalue;
+
+ /* Flush the read and cmd queue. */
+ value=( EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH );
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
+ value=0;
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
+
+ /* Clear the Avail/Full bits. */
+ value=( EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL );
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+
+ value= dwAddress | ( (dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ );
+ wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
+
+ while ( dwRetries != 0 )
+ {
+
+ uiStatus = 0;
+ rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem has got Removed.hence exiting from loop...");
+ return -ENODEV;
+ }
+
+ /* If we are reading 16 bytes we want to be sure that the queue
+ * is full before we read. In the other cases we are ok if the
+ * queue has data available */
+ if ( dwNumWords == 4 )
+ {
+ if ( ( uiStatus & EEPROM_READ_DATA_FULL ) != 0 )
+ {
+ /* Clear the Avail/Full bits - which ever is set. */
+ value = ( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) ) ;
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ break;
+ }
+ }
+ else if ( dwNumWords == 1 )
+ {
+
+ if ( ( uiStatus & EEPROM_READ_DATA_AVAIL ) != 0 )
+ {
+ /* We just got Avail and we have to read 32bits so we
+ * need this sleep for Cardbus kind of devices. */
+ if (Adapter->chip_id == 0xBECE0210 )
+ udelay(800);
+
+ /* Clear the Avail/Full bits - which ever is set. */
+ value=( uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL) );
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ break;
+ }
+ }
+
+ uiStatus = 0;
+
+ dwRetries--;
+ if(dwRetries == 0)
+ {
+ value=0;
+ value1=0;
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG,&value1, sizeof(value1));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n", dwNumWords, value, value1, MAX_EEPROM_RETRIES*RETRIES_PER_DELAY);
+ return STATUS_FAILURE;
+ }
+ if( !(dwRetries%RETRIES_PER_DELAY) )
+ msleep(1);
+ }
+
+ for ( dwIndex = 0; dwIndex < dwNumWords ; dwIndex++ )
+ {
+ /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */
+ pvalue = (PUCHAR)(pdwData + dwIndex);
+
+ value =0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+
+ pvalue[0] = value;
+
+ value = 0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+
+ pvalue[1] = value;
+
+ value =0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+
+ pvalue[2] = value;
+
+ value = 0;
+ rdmalt(Adapter, EEPROM_READ_DATAQ_REG,&value, sizeof(value));
+
+ pvalue[3] = value;
+ }
+
+ return STATUS_SUCCESS;
+} /* ReadBeceemEEPROMBulk() */
+
+//-----------------------------------------------------------------------------
+// Procedure: ReadBeceemEEPROM
+//
+// Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page
+// reads to do this operation.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - EEPROM Offset to read the data from.
+// pBuffer - Pointer to word where data needs to be stored in.
+//
+// Returns:
+// OSAL_STATUS_CODE:
+//-----------------------------------------------------------------------------
+
+INT ReadBeceemEEPROM( PMINI_ADAPTER Adapter,
+ DWORD uiOffset,
+ DWORD *pBuffer
+ )
+{
+ UINT uiData[8] = {0};
+ UINT uiByteOffset = 0;
+ UINT uiTempOffset = 0;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," ====> ");
+
+ uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
+ uiByteOffset = uiOffset - uiTempOffset;
+
+ ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
+
+ /* A word can overlap at most over 2 pages. In that case we read the
+ * next page too. */
+ if ( uiByteOffset > 12 )
+ {
+ ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
+ }
+
+ OsalMemMove( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4);
+
+ return STATUS_SUCCESS;
+} /* ReadBeceemEEPROM() */
+
+
+#if 0
+//-----------------------------------------------------------------------------
+// Procedure: IsEEPROMWriteDone
+//
+// Description: Reads the SPI status to see the status of previous write.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// BOOLEAN - TRUE - write went through
+// - FALSE - Write Failed.
+//-----------------------------------------------------------------------------
+
+BOOLEAN IsEEPROMWriteDone(PMINI_ADAPTER Adapter)
+{
+ UINT uiRetries = 16;
+ //UINT uiStatus = 0;
+ UINT value;
+
+ //sleep for 1.2ms ..worst case EEPROM write can take up to 1.2ms.
+ mdelay(2);
+
+ value = 0;
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+
+ while(((value >> 14) & 1) == 1)
+ {
+ // EEPROM_SPI_Q_STATUS1_REG will be cleared only if write back to that.
+ value = (0x1 << 14);
+ wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+ udelay(1000);
+ uiRetries--;
+ if(uiRetries == 0)
+ {
+ return FALSE;
+ }
+ value = 0;
+ rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+ }
+ return TRUE;
+
+
+}
+
+
+//-----------------------------------------------------------------------------
+// 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.
+//
+// Returns:
+// OSAL_STATUS_CODE:
+//-----------------------------------------------------------------------------
+
+INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData)
+{
+ DWORD dwRetries = 16;
+ DWORD dwIndex = 0;
+ UINT value, tmpVal;
+
+
+ value = 0;
+ rdmalt (Adapter, 0x0f003008, &value, sizeof(value));
+
+ //read 0x0f003020 untill bit 1 of 0x0f003008 is set.
+ while(((value >> 1) & 1) == 0)
+ {
+
+ rdmalt (Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal));
+ dwRetries--;
+ if(dwRetries == 0)
+ {
+ return -1;
+ }
+ value = 0;
+ rdmalt (Adapter, 0x0f003008, &value, sizeof(value));
+ }
+
+ value = dwAddress | 0xfb000000;
+ wrmalt (Adapter, 0x0f003018, &value, sizeof(value));
+
+ udelay(1000);
+ value = 0;
+ for(dwIndex = 0;dwIndex < 4 ; dwIndex++)
+ {
+ value = 0;
+ rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
+ pdwData[dwIndex] = value;
+
+ value = 0;
+ rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
+ pdwData[dwIndex] |= (value << 8);
+
+ value = 0;
+ rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
+ pdwData[dwIndex] |= (value << 16);
+
+ value = 0;
+ rdmalt (Adapter, 0x0f003020, &value, sizeof(value));
+ pdwData[dwIndex] |= (value << 24);
+
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: ReadBeceemEEPROM
+//
+// Description: This routine reads 4Byte 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.
+//
+// Returns:
+// OSAL_STATUS_CODE:
+//-----------------------------------------------------------------------------
+
+INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData)
+{
+
+ DWORD dwReadValue = 0;
+ DWORD dwRetries = 16, dwCompleteWord = 0;
+ UINT value, tmpVal;
+
+ rdmalt(Adapter, 0x0f003008, &value, sizeof(value));
+ while (((value >> 1) & 1) == 0) {
+ rdmalt(Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal));
+
+ if (dwRetries == 0) {
+ return -1;
+ }
+ rdmalt(Adapter, 0x0f003008, &value, sizeof(value));
+ }
+
+
+ //wrm (0x0f003018, 0xNbXXXXXX) // N is the number of bytes u want to read (0 means 1, f means 16, b is the opcode for page read)
+ // Follow it up by N executions of rdm(0x0f003020) to read the rxed bytes from rx queue.
+ dwAddress |= 0x3b000000;
+ wrmalt(Adapter, 0x0f003018,&dwAddress,4);
+ mdelay(10);
+ rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
+ dwCompleteWord=dwReadValue;
+ rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
+ dwCompleteWord|=(dwReadValue<<8);
+ rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
+ dwCompleteWord|=(dwReadValue<<16);
+ rdmalt(Adapter, 0x0f003020,&dwReadValue,4);
+ dwCompleteWord|=(dwReadValue<<24);
+
+ *pdwData = dwCompleteWord;
+
+ return 0;
+}
+#endif
+
+INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter)
+{
+ INT Status=0, i;
+ unsigned char puMacAddr[6] = {0};
+ INT AllZeroMac = 0;
+ INT AllFFMac = 0;
+
+ Status = BeceemNVMRead(Adapter,
+ (PUINT)&puMacAddr[0],
+ INIT_PARAMS_1_MACADDRESS_ADDRESS,
+ MAC_ADDRESS_SIZE);
+
+ if(Status != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Error in Reading the mac Addres with status :%d", Status);
+ return Status;
+ }
+
+ memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Modem MAC Addr :");
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_PRINTK, 0, DBG_LVL_ALL,&Adapter->dev->dev_addr[0],MAC_ADDRESS_SIZE);
+ for(i=0;i<MAC_ADDRESS_SIZE;i++)
+ {
+
+ if(Adapter->dev->dev_addr[i] == 0x00)
+ AllZeroMac++;
+ if(Adapter->dev->dev_addr[i] == 0xFF)
+ AllFFMac++;
+
+ }
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\n");
+ if(AllZeroMac == MAC_ADDRESS_SIZE)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all 00's");
+ if(AllFFMac == MAC_ADDRESS_SIZE)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all FF's");
+
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemEEPROMBulkRead
+//
+// Description: Reads the EEPROM and returns the Data.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Buffer to store the data read from EEPROM
+// uiOffset - Offset of EEPROM from where data should be read
+// uiNumBytes - Number of bytes to be read from the EEPROM.
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if EEPROM read is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BeceemEEPROMBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes)
+{
+ UINT uiData[4] = {0};
+ //UINT uiAddress = 0;
+ UINT uiBytesRemaining = uiNumBytes;
+ UINT uiIndex = 0;
+ UINT uiTempOffset = 0;
+ UINT uiExtraBytes = 0;
+ UINT uiFailureRetries = 0;
+ PUCHAR pcBuff = (PUCHAR)pBuffer;
+
+
+ if(uiOffset%MAX_RW_SIZE&& uiBytesRemaining)
+ {
+ uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
+ uiExtraBytes = uiOffset-uiTempOffset;
+ ReadBeceemEEPROMBulk(Adapter,uiTempOffset,(PUINT)&uiData[0],4);
+ if(uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes))
+ {
+ OsalMemMove(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
+ {
+ OsalMemMove(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining);
+ uiIndex += uiBytesRemaining;
+ uiOffset += uiBytesRemaining;
+ uiBytesRemaining = 0;
+ }
+
+
+ }
+
+
+ while(uiBytesRemaining && uiFailureRetries != 128)
+ {
+ if(Adapter->device_removed )
+ {
+ return -1;
+ }
+
+ if(uiBytesRemaining >= MAX_RW_SIZE)
+ {
+ /* For the requests more than or equal to 16 bytes, use bulk
+ * read function to make the access faster.
+ * We read 4 Dwords of data */
+ if(0 == ReadBeceemEEPROMBulk(Adapter,uiOffset,&uiData[0],4))
+ {
+ OsalMemMove(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE);
+ uiOffset += MAX_RW_SIZE;
+ uiBytesRemaining -= MAX_RW_SIZE;
+ uiIndex += MAX_RW_SIZE;
+ }
+ else
+ {
+ uiFailureRetries++;
+ mdelay(3);//sleep for a while before retry...
+ }
+ }
+ else if(uiBytesRemaining >= 4)
+ {
+ if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
+ {
+ OsalMemMove(pcBuff+uiIndex,&uiData[0],4);
+ uiOffset += 4;
+ uiBytesRemaining -= 4;
+ uiIndex +=4;
+ }
+ else
+ {
+ uiFailureRetries++;
+ mdelay(3);//sleep for a while before retry...
+ }
+ }
+ else
+ { // Handle the reads less than 4 bytes...
+ PUCHAR pCharBuff = (PUCHAR)pBuffer;
+ pCharBuff += uiIndex;
+ if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0]))
+ {
+ OsalMemMove(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested.
+ uiBytesRemaining = 0;
+ }
+ else
+ {
+ uiFailureRetries++;
+ mdelay(3);//sleep for a while before retry...
+ }
+ }
+
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemFlashBulkRead
+//
+// Description: Reads the FLASH and returns the Data.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Buffer to store the data read from FLASH
+// uiOffset - Offset of FLASH from where data should be read
+// uiNumBytes - Number of bytes to be read from the FLASH.
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if FLASH read is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BeceemFlashBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes)
+{
+ UINT uiIndex = 0;
+ UINT uiBytesToRead = uiNumBytes;
+ INT Status = 0;
+ UINT uiPartOffset = 0;
+
+ if(Adapter->device_removed )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device Got Removed ");
+ return -ENODEV;
+ }
+
+ //Adding flash Base address
+// uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
+#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
+ Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
+ return Status;
+#endif
+
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+
+ if(uiOffset % MAX_RW_SIZE)
+ {
+ BcmDoChipSelect(Adapter,uiOffset);
+ uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
+
+ uiBytesToRead = MAX_RW_SIZE - (uiOffset%MAX_RW_SIZE);
+ uiBytesToRead = MIN(uiNumBytes,uiBytesToRead);
+
+ if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
+ {
+ Status = -1;
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ return Status;
+ }
+
+ uiIndex += uiBytesToRead;
+ uiOffset += uiBytesToRead;
+ uiNumBytes -= uiBytesToRead;
+ }
+
+ while(uiNumBytes)
+ {
+ BcmDoChipSelect(Adapter,uiOffset);
+ uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
+
+ uiBytesToRead = MIN(uiNumBytes,MAX_RW_SIZE);
+
+ if(rdm(Adapter,uiPartOffset, (PCHAR)pBuffer+uiIndex,uiBytesToRead))
+ {
+ Status = -1;
+ break;
+ }
+
+
+ uiIndex += uiBytesToRead;
+ uiOffset += uiBytesToRead;
+ uiNumBytes -= uiBytesToRead;
+
+ }
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ return Status;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetFlashSize
+//
+// Description: Finds the size of FLASH.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// UINT - size of the FLASH Storage.
+//
+//-----------------------------------------------------------------------------
+
+UINT BcmGetFlashSize(PMINI_ADAPTER Adapter)
+{
+#if 0
+ if(Adapter->bDDRInitDone)
+ {
+ return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT|FLASH_SIZE_ADDR);
+ }
+
+ return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT|FLASH_SIZE_ADDR);
+#endif
+ if(IsFlash2x(Adapter))
+ return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER));
+ else
+ return 32*1024;
+
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetEEPROMSize
+//
+// Description: Finds the size of EEPROM.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// UINT - size of the EEPROM Storage.
+//
+//-----------------------------------------------------------------------------
+
+UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter)
+{
+ UINT uiData = 0;
+ UINT uiIndex = 0;
+
+//
+// if EEPROM is present and already Calibrated,it will have
+// 'BECM' string at 0th offset.
+// To find the EEPROM size read the possible boundaries of the
+// EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will
+// result in wrap around. So when we get the End of the EEPROM we will
+// get 'BECM' string which is indeed at offset 0.
+//
+ BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
+ if(uiData == BECM)
+ {
+ for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
+ {
+ BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
+ if(uiData == BECM)
+ {
+ return uiIndex*1024;
+ }
+ }
+ }
+ else
+ {
+//
+// EEPROM may not be present or not programmed
+//
+
+ uiData = 0xBABEFACE;
+ if(0 == BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&uiData,0,4,TRUE))
+ {
+ uiData = 0;
+ for(uiIndex = 2;uiIndex <=256; uiIndex*=2)
+ {
+ BeceemEEPROMBulkRead(Adapter,&uiData,uiIndex*1024,4);
+ if(uiData == 0xBABEFACE)
+ {
+ return uiIndex*1024;
+ }
+ }
+ }
+
+ }
+ return 0;
+}
+
+#if 0
+/***********************************************************************************/
+//
+// WriteBeceemEEPROM: Writes 4 byte data to EEPROM offset.
+//
+// uiEEPROMOffset - Offset to be written to.
+// uiData - Data to be written.
+//
+/***********************************************************************************/
+
+INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData)
+{
+ INT Status = 0;
+ ULONG ulRdBk = 0;
+ ULONG ulRetryCount = 3;
+ UINT value;
+
+ if(uiEEPROMOffset > EEPROM_END)
+ {
+
+ return -1;
+ }
+
+ uiData = htonl(uiData);
+ while(ulRetryCount--)
+ {
+ value = 0x06000000;
+ wrmalt(Adapter, 0x0F003018,&value, sizeof(value));//flush the EEPROM FIFO.
+ wrmalt(Adapter, 0x0F00301C,&uiData, sizeof(uiData));
+ value = 0x3A000000 | uiEEPROMOffset;
+ wrmalt(Adapter, 0x0F003018,&value, sizeof(value));
+ __udelay(100000);
+ //read back and verify.
+ Status = ReadBeceemEEPROM(Adapter,uiEEPROMOffset,(UINT *)&ulRdBk);
+ if(Status == 0)
+ {
+ if(ulRdBk == uiData)
+ {
+ return Status;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback does not match\n");
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback failed\n");
+ }
+ }
+
+ return 0;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Procedure: FlashSectorErase
+//
+// Description: Finds the sector size of the FLASH.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// addr - sector start address
+// numOfSectors - number of sectors to be erased.
+//
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+
+static INT FlashSectorErase(PMINI_ADAPTER Adapter,
+ UINT addr,
+ UINT numOfSectors)
+{
+ UINT iIndex = 0, iRetries = 0;
+ UINT uiStatus = 0;
+ UINT value;
+
+ for(iIndex=0;iIndex<numOfSectors;iIndex++)
+ {
+ value = 0x06000000;
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+
+ value = (0xd8000000 | (addr & 0xFFFFFF));
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ iRetries = 0;
+
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ iRetries++;
+ //After every try lets make the CPU free for 10 ms. generally time taken by the
+ //the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms
+ //won't hamper performance in any case.
+ msleep(10);
+ }while((uiStatus & 0x1) && (iRetries < 400));
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"iRetries crossing the limit of 80000\n");
+ return STATUS_FAILURE;
+ }
+
+ addr += Adapter->uiSectorSize;
+ }
+ return 0;
+}
+//-----------------------------------------------------------------------------
+// Procedure: flashByteWrite
+//
+// Description: Performs Byte by Byte write to flash
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to.
+// pData - Address of Data to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+static INT flashByteWrite(
+ PMINI_ADAPTER Adapter,
+ UINT uiOffset,
+ PVOID pData)
+{
+
+ UINT uiStatus = 0;
+ INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
+
+ UINT value;
+ ULONG ulData = *(PUCHAR)pData;
+
+//
+// need not write 0xFF because write requires an erase and erase will
+// make whole sector 0xFF.
+//
+
+ if(0xFF == ulData)
+ {
+ return STATUS_SUCCESS;
+ }
+
+// DumpDebug(NVM_RW,("flashWrite ====>\n"));
+ value = (FLASH_CMD_WRITE_ENABLE << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
+ return STATUS_FAILURE;
+ }
+ if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ value = (0x02000000 | (uiOffset & 0xFFFFFF));
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ //__udelay(950);
+
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ //__udelay(1);
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ iRetries--;
+ if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
+ msleep(1);
+
+ }while((uiStatus & 0x1) && (iRetries >0) );
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
+ return STATUS_FAILURE ;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Procedure: flashWrite
+//
+// Description: Performs write to flash
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to.
+// pData - Address of Data to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+static INT flashWrite(
+ PMINI_ADAPTER Adapter,
+ UINT uiOffset,
+ PVOID pData)
+
+{
+ //UINT uiStatus = 0;
+ //INT iRetries = 0;
+ //UINT uiReadBack = 0;
+
+ UINT uiStatus = 0;
+ INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
+
+ UINT value;
+ UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+//
+// need not write 0xFFFFFFFF because write requires an erase and erase will
+// make whole sector 0xFFFFFFFF.
+//
+ if (!OsalMemCompare(pData, uiErasePattern, MAX_RW_SIZE))
+ {
+ return 0;
+ }
+
+ value = (FLASH_CMD_WRITE_ENABLE << 24);
+
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
+ return STATUS_FAILURE;
+ }
+
+ //__udelay(950);
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ //__udelay(1);
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ iRetries--;
+ //this will ensure that in there will be no changes in the current path.
+ //currently one rdm/wrm takes 125 us.
+ //Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay)
+ //Hence current implementation cycle will intoduce no delay in current path
+ if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
+ msleep(1);
+ }while((uiStatus & 0x1) && (iRetries > 0));
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
+ return STATUS_FAILURE ;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: flashByteWriteStatus
+//
+// Description: Performs byte by byte write to flash with write done status check
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to.
+// pData - Address of the Data to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+static INT flashByteWriteStatus(
+ PMINI_ADAPTER Adapter,
+ UINT uiOffset,
+ PVOID pData)
+{
+ UINT uiStatus = 0;
+ INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
+ ULONG ulData = *(PUCHAR)pData;
+ UINT value;
+
+//
+// need not write 0xFFFFFFFF because write requires an erase and erase will
+// make whole sector 0xFFFFFFFF.
+//
+
+ if(0xFF == ulData)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ // DumpDebug(NVM_RW,("flashWrite ====>\n"));
+
+ value = (FLASH_CMD_WRITE_ENABLE << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write enable in FLASH_SPI_CMDQ_REG register fails");
+ return STATUS_SUCCESS;
+ }
+ if(wrm(Adapter,FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DATA Write on FLASH_SPI_WRITEQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ value = (0x02000000 | (uiOffset & 0xFFFFFF));
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programming of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ //msleep(1);
+
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ //__udelay(1);
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+
+ iRetries--;
+ if( iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
+ msleep(1);
+ }while((uiStatus & 0x1) && (iRetries > 0));
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
+ return STATUS_FAILURE ;
+ }
+
+ return STATUS_SUCCESS;
+
+}
+//-----------------------------------------------------------------------------
+// Procedure: flashWriteStatus
+//
+// Description: Performs write to flash with write done status check
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to.
+// pData - Address of the Data to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+static INT flashWriteStatus(
+ PMINI_ADAPTER Adapter,
+ UINT uiOffset,
+ PVOID pData)
+{
+ UINT uiStatus = 0;
+ INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
+ //UINT uiReadBack = 0;
+ UINT value;
+ UINT uiErasePattern[4] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+
+//
+// need not write 0xFFFFFFFF because write requires an erase and erase will
+// make whole sector 0xFFFFFFFF.
+//
+ if (!OsalMemCompare(pData,uiErasePattern,MAX_RW_SIZE))
+ {
+ return 0;
+ }
+
+ value = (FLASH_CMD_WRITE_ENABLE << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Write Enable of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ if(wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Data write fails...");
+ return STATUS_FAILURE;
+ }
+ // __udelay(1);
+
+ do
+ {
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ if(wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Programing of FLASH_SPI_CMDQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ //__udelay(1);
+ if(rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus)) < 0)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Reading status of FLASH_SPI_READQ_REG fails");
+ return STATUS_FAILURE;
+ }
+ iRetries--;
+ //this will ensure that in there will be no changes in the current path.
+ //currently one rdm/wrm takes 125 us.
+ //Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay)
+ //Hence current implementation cycle will intoduce no delay in current path
+ if(iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
+ msleep(1);
+ }while((uiStatus & 0x1) && (iRetries >0));
+
+ if(uiStatus & 0x1)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Write fails even after checking status for 200 times.");
+ return STATUS_FAILURE ;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmRestoreBlockProtectStatus
+//
+// Description: Restores the original block protection status.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// ulWriteStatus -Original status
+// Returns:
+// <VOID>
+//
+//-----------------------------------------------------------------------------
+
+static VOID BcmRestoreBlockProtectStatus(PMINI_ADAPTER Adapter,ULONG ulWriteStatus)
+{
+ UINT value;
+ value = (FLASH_CMD_WRITE_ENABLE<< 24);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+
+ udelay(20);
+ value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ udelay(20);
+}
+//-----------------------------------------------------------------------------
+// Procedure: BcmFlashUnProtectBlock
+//
+// Description: UnProtects appropriate blocks for writing.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned.
+// Returns:
+// ULONG - Status value before UnProtect.
+//
+//-----------------------------------------------------------------------------
+static ULONG BcmFlashUnProtectBlock(PMINI_ADAPTER Adapter,UINT uiOffset, UINT uiLength)
+{
+ ULONG ulStatus = 0;
+ ULONG ulWriteStatus = 0;
+ UINT value;
+ uiOffset = uiOffset&0x000FFFFF;
+
+//
+// Implemented only for 1MB Flash parts.
+//
+ if(FLASH_PART_SST25VF080B == Adapter->ulFlashID)
+ {
+ //
+ // Get Current BP status.
+ //
+ value = (FLASH_CMD_STATUS_REG_READ << 24);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ udelay(10);
+ //
+ // Read status will be WWXXYYZZ. We have to take only WW.
+ //
+ rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
+ ulStatus >>= 24;
+ ulWriteStatus = ulStatus;
+
+ //
+ // Bits [5-2] give current block level protection status.
+ // Bit5: BP3 - DONT CARE
+ // BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4
+ // 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS
+ //
+
+ if(ulStatus)
+ {
+ if((uiOffset+uiLength) <= 0x80000)
+ {
+ //
+ // Offset comes in lower half of 1MB. Protect the upper half.
+ // Clear BP1 and BP0 and set BP2.
+ //
+ ulWriteStatus |= (0x4<<2);
+ ulWriteStatus &= ~(0x3<<2);
+ }
+ else if((uiOffset+uiLength) <= 0xC0000)
+ {
+ //
+ // Offset comes below Upper 1/4. Upper 1/4 can be protected.
+ // Clear BP2 and set BP1 and BP0.
+ //
+ ulWriteStatus |= (0x3<<2);
+ ulWriteStatus &= ~(0x1<<4);
+ }
+ else if((uiOffset+uiLength) <= 0xE0000)
+ {
+ //
+ // Offset comes below Upper 1/8. Upper 1/8 can be protected.
+ // Clear BP2 and BP0 and set BP1
+ //
+ ulWriteStatus |= (0x1<<3);
+ ulWriteStatus &= ~(0x5<<2);
+
+ }
+ else if((uiOffset+uiLength) <= 0xF0000)
+ {
+ //
+ // Offset comes below Upper 1/16. Only upper 1/16 can be protected.
+ // Set BP0 and Clear BP2,BP1.
+ //
+ ulWriteStatus |= (0x1<<2);
+ ulWriteStatus &= ~(0x3<<3);
+ }
+ else
+ {
+ //
+ // Unblock all.
+ // Clear BP2,BP1 and BP0.
+ //
+ ulWriteStatus &= ~(0x7<<2);
+ }
+
+ value = (FLASH_CMD_WRITE_ENABLE<< 24);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ udelay(20);
+ value = (FLASH_CMD_STATUS_REG_WRITE<<24)|(ulWriteStatus << 16);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
+ udelay(20);
+
+ }
+
+ }
+ return ulStatus;
+}
+//-----------------------------------------------------------------------------
+// Procedure: BeceemFlashBulkWrite
+//
+// Description: Performs write to the flash
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Data to be written.
+// uiOffset - Offset of the flash where data needs to be written to.
+// uiNumBytes - Number of bytes to be written.
+// bVerify - read verify flag.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT BeceemFlashBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify)
+{
+ PCHAR pTempBuff = NULL;
+ PUCHAR pcBuffer = (PUCHAR)pBuffer;
+ UINT uiIndex = 0;
+ UINT uiOffsetFromSectStart = 0;
+ UINT uiSectAlignAddr = 0;
+ UINT uiCurrSectOffsetAddr = 0;
+ UINT uiSectBoundary = 0;
+ UINT uiNumSectTobeRead = 0;
+ UCHAR ucReadBk[16] = {0};
+ ULONG ulStatus = 0;
+ INT Status = STATUS_SUCCESS;
+ UINT uiTemp = 0;
+ UINT index = 0;
+ UINT uiPartOffset = 0;
+ #if 0
+ struct timeval tv1 = {0};
+ struct timeval tv2 = {0};
+
+ struct timeval tr = {0};
+ struct timeval te = {0};
+ struct timeval tw = {0};
+ struct timeval twv = {0};
+ #endif
+
+#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 = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN');
+ pTempBuff = OsalMemAlloc(Adapter->uiSectorSize ,"!MVN");
+ if(NULL == pTempBuff)
+ {
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+//
+// check if the data to be written is overlapped accross sectors
+//
+ if(uiOffset+uiNumBytes < uiSectBoundary)
+ {
+ uiNumSectTobeRead = 1;
+ }
+ else
+ {
+ // Number of sectors = Last sector start address/First sector start address
+ uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
+ if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
+ {
+ uiNumSectTobeRead++;
+ }
+ }
+ #if 1
+ //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 ;
+ }
+ }
+ #endif
+ 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)
+ {
+
+ OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+ pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
+ uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+ }
+ else
+ {
+ OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes);
+ }
+
+ if(IsFlash2x(Adapter))
+ {
+ SaveHeaderIfPresent(Adapter,(PUCHAR)pTempBuff,uiOffsetFromSectStart);
+ }
+
+ FlashSectorErase(Adapter,uiPartOffset,1);
+ //do_gettimeofday(&te);
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken by Erase :%ld ms\n", (te.tv_sec *1000 + te.tv_usec/1000) - (tr.tv_sec *1000 + tr.tv_usec/1000));
+
+ for(uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex +=Adapter->ulFlashWriteSize)
+ {
+ if(Adapter->device_removed)
+ {
+ Status = -1;
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+ if(STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter,uiPartOffset+uiIndex,(&pTempBuff[uiIndex])))
+ {
+ Status = -1;
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+ }
+
+ //do_gettimeofday(&tw);
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000));
+ for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE)
+ {
+ if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
+ {
+ if(Adapter->ulFlashWriteSize == 1)
+ {
+ UINT uiReadIndex = 0;
+ for(uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++)
+ {
+ if(ucReadBk[uiReadIndex] != pTempBuff[uiIndex+uiReadIndex])
+ {
+ if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex+uiReadIndex,&pTempBuff[uiIndex+uiReadIndex]))
+ {
+ Status = STATUS_FAILURE;
+ goto BeceemFlashBulkWrite_EXIT;
+ }
+ }
+ }
+ }
+ else
+ {
+ if(OsalMemCompare(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);
+ }
+ if(pTempBuff)
+ {
+ OsalMemFree(pTempBuff,Adapter->uiSectorSize);
+ }
+
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ return Status;
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemFlashBulkWriteStatus
+//
+// Description: Writes to Flash. Checks the SPI status after each write.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Data to be written.
+// uiOffset - Offset of the flash where data needs to be written to.
+// uiNumBytes - Number of bytes to be written.
+// bVerify - read verify flag.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+static INT BeceemFlashBulkWriteStatus(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify)
+{
+ PCHAR pTempBuff = NULL;
+ PUCHAR pcBuffer = (PUCHAR)pBuffer;
+ UINT uiIndex = 0;
+ UINT uiOffsetFromSectStart = 0;
+ UINT uiSectAlignAddr = 0;
+ UINT uiCurrSectOffsetAddr = 0;
+ UINT uiSectBoundary = 0;
+ UINT uiNumSectTobeRead = 0;
+ UCHAR ucReadBk[16] = {0};
+ ULONG ulStatus = 0;
+ UINT Status = STATUS_SUCCESS;
+ UINT uiTemp = 0;
+ UINT index = 0;
+ UINT uiPartOffset = 0;
+
+ uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
+
+ //uiOffset += Adapter->ulFlashCalStart;
+ //Adding flash Base address
+// uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
+
+ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
+ uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
+ uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
+
+
+
+// pTempBuff = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN');
+ pTempBuff = OsalMemAlloc(Adapter->uiSectorSize,"!MVN");
+ if(NULL == pTempBuff)
+ {
+ goto BeceemFlashBulkWriteStatus_EXIT;
+ }
+//
+// check if the data to be written is overlapped accross sectors
+//
+ if(uiOffset+uiNumBytes < uiSectBoundary)
+ {
+ uiNumSectTobeRead = 1;
+ }
+ else
+ {
+// Number of sectors = Last sector start address/First sector start address
+ uiNumSectTobeRead = (uiCurrSectOffsetAddr+uiNumBytes)/Adapter->uiSectorSize;
+ if((uiCurrSectOffsetAddr+uiNumBytes)%Adapter->uiSectorSize)
+ {
+ uiNumSectTobeRead++;
+ }
+ }
+
+ if(IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE))
+ {
+ index = 0;
+ uiTemp = uiNumSectTobeRead ;
+ while(uiTemp)
+ {
+ if(IsOffsetWritable(Adapter,uiOffsetFromSectStart + index * Adapter->uiSectorSize ) == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Sector Starting at offset <0X%x> is not writable",
+ (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
+ Status = SECTOR_IS_NOT_WRITABLE;
+ goto BeceemFlashBulkWriteStatus_EXIT;
+ }
+ uiTemp = uiTemp - 1;
+ index = index + 1 ;
+ }
+ }
+
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ while(uiNumSectTobeRead)
+ {
+ uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
+
+ BcmDoChipSelect(Adapter,uiSectAlignAddr);
+ if(0 != BeceemFlashBulkRead(Adapter,
+ (PUINT)pTempBuff,
+ uiOffsetFromSectStart,
+ Adapter->uiSectorSize))
+ {
+ Status = -1;
+ goto BeceemFlashBulkWriteStatus_EXIT;
+ }
+
+ ulStatus = BcmFlashUnProtectBlock(Adapter,uiOffsetFromSectStart,Adapter->uiSectorSize);
+
+ if(uiNumSectTobeRead > 1)
+ {
+
+ OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+ pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)));
+ uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr));
+ }
+ else
+ {
+ OsalMemMove(&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 0
+ if(0 == BeceemFlashBulkRead(Adapter,uiReadBk,uiOffsetFromSectStart+uiIndex + Adapter->ulFlashCalStart ,MAX_RW_SIZE))
+ {
+ for(uiReadIndex = 0;uiReadIndex < 4; uiReadIndex++)
+ {
+ if(*((PUINT)&pTempBuff[uiIndex+uiReadIndex*4]) != uiReadBk[uiReadIndex])
+ {
+ Status = -1;
+ goto BeceemFlashBulkWriteStatus_EXIT;
+
+ }
+ }
+
+ }
+#endif
+
+ if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE))
+ {
+ if(OsalMemCompare(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);
+ }
+ if(pTempBuff)
+ {
+ OsalMemFree(pTempBuff,Adapter->uiSectorSize);
+ }
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: PropagateCalParamsFromEEPROMToMemory
+//
+// Description: Dumps the calibration section of EEPROM to DDR.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+
+INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter)
+{
+ PCHAR pBuff = OsalMemAlloc(BUFFER_4K,"3MVN");
+ UINT uiEepromSize = 0;
+ UINT uiIndex = 0;
+ UINT uiBytesToCopy = 0;
+ UINT uiCalStartAddr = EEPROM_CALPARAM_START;
+ UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
+ UINT value;
+ INT Status = 0;
+ if(pBuff == NULL)
+ {
+ return -1;
+ }
+
+ if(0 != BeceemEEPROMBulkRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET,4))
+ {
+
+ OsalMemFree(pBuff,BUFFER_4K);
+ return -1;
+ }
+
+ uiEepromSize >>= 16;
+ if(uiEepromSize > 1024*1024)
+ {
+ OsalMemFree(pBuff,BUFFER_4K);
+ 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));
+ OsalMemFree(pBuff,MAX_RW_SIZE);
+
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: PropagateCalParamsFromFlashToMemory
+//
+// Description: Dumps the calibration section of EEPROM to DDR.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter)
+{
+ PCHAR pBuff, pPtr;
+ UINT uiEepromSize = 0;
+ UINT uiBytesToCopy = 0;
+ //UINT uiIndex = 0;
+ UINT uiCalStartAddr = EEPROM_CALPARAM_START;
+ UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
+ UINT value;
+ INT Status = 0;
+//
+// Write the signature first. This will ensure firmware does not access EEPROM.
+//
+ value = 0xbeadbead;
+ wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
+ value = 0xbeadbead;
+ wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
+
+ if(0 != BeceemNVMRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET, 4))
+ {
+ return -1;
+ }
+ uiEepromSize = ntohl(uiEepromSize);
+ uiEepromSize >>= 16;
+
+//
+// subtract the auto init section size
+//
+ uiEepromSize -= EEPROM_CALPARAM_START;
+
+ if(uiEepromSize > 1024*1024)
+ {
+ return -1;
+ }
+
+ pBuff = OsalMemAlloc(uiEepromSize, 0);
+
+ if ( pBuff == NULL )
+ {
+ return -1;
+ }
+
+ if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize))
+ {
+ OsalMemFree(pBuff, 0);
+ 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);
+ }
+
+ OsalMemFree(pBuff, 0);
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemEEPROMReadBackandVerify
+//
+// Description: Read back the data written and verifies.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Data to be written.
+// uiOffset - Offset of the flash where data needs to be written to.
+// uiNumBytes - Number of bytes to be written.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+static INT BeceemEEPROMReadBackandVerify(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes)
+{
+ UINT uiRdbk = 0;
+ UINT uiIndex = 0;
+ UINT uiData = 0;
+ UINT auiData[4] = {0};
+
+ while(uiNumBytes)
+ {
+ if(Adapter->device_removed )
+ {
+ return -1;
+ }
+
+ if(uiNumBytes >= MAX_RW_SIZE)
+ {// for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster.
+ BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE);
+
+ if(OsalMemCompare(&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(OsalMemCompare(&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;
+ OsalMemMove(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes);
+ BeceemEEPROMBulkRead(Adapter,&uiRdbk,uiOffset,4);
+
+ if(memcmp(&uiData, &uiRdbk, uiNumBytes))
+ return -1;
+
+ uiNumBytes = 0;
+ }
+
+ }
+
+ return 0;
+}
+
+static VOID BcmSwapWord(UINT *ptr1) {
+
+ UINT tempval = (UINT)*ptr1;
+ char *ptr2 = (char *)&tempval;
+ char *ptr = (char *)ptr1;
+
+ ptr[0] = ptr2[3];
+ ptr[1] = ptr2[2];
+ ptr[2] = ptr2[1];
+ ptr[3] = ptr2[0];
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemEEPROMWritePage
+//
+// Description: Performs page write (16bytes) to the EEPROM
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiData - Data to be written.
+// uiOffset - Offset of the EEPROM where data needs to be written to.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+static INT BeceemEEPROMWritePage( PMINI_ADAPTER Adapter, UINT uiData[], UINT uiOffset )
+{
+ UINT uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
+ UINT uiStatus = 0;
+ UCHAR uiEpromStatus = 0;
+ UINT value =0 ;
+
+ /* Flush the Write/Read/Cmd queues. */
+ value = ( EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH );
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
+ value = 0 ;
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
+
+ /* Clear the Empty/Avail/Full bits. After this it has been confirmed
+ * that the bit was cleared by reading back the register. See NOTE below.
+ * We also clear the Read queues as we do a EEPROM status register read
+ * later. */
+ value = ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL ) ;
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value));
+
+ /* Enable write */
+ value = EEPROM_WRITE_ENABLE ;
+ wrmalt( Adapter, EEPROM_CMDQ_SPI_REG,&value, sizeof(value) );
+
+ /* We can write back to back 8bits * 16 into the queue and as we have
+ * checked for the queue to be empty we can write in a burst. */
+
+ value = uiData[0];
+ BcmSwapWord(&value);
+ wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
+
+ value = uiData[1];
+ BcmSwapWord(&value);
+ wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
+
+ value = uiData[2];
+ BcmSwapWord(&value);
+ wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
+
+ value = uiData[3];
+ BcmSwapWord(&value);
+ wrm( Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
+
+ /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG
+ * shows that we see 7 for the EEPROM data write. Which means that
+ * queue got full, also space is available as well as the queue is empty.
+ * This may happen in sequence. */
+ value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset ;
+ wrmalt( Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value) );
+
+ /* Ideally we should loop here without tries and eventually succeed.
+ * What we are checking if the previous write has completed, and this
+ * may take time. We should wait till the Empty bit is set. */
+ uiStatus = 0;
+ rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
+ while ( ( uiStatus & EEPROM_WRITE_QUEUE_EMPTY ) == 0 )
+ {
+ uiRetries--;
+ if ( uiRetries == 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY);
+ return STATUS_FAILURE ;
+ }
+
+ if( !(uiRetries%RETRIES_PER_DELAY) )
+ msleep(1);
+
+ uiStatus = 0;
+ rdmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG,&uiStatus, sizeof(uiStatus)) ;
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Modem got removed hence exiting from loop....");
+ return -ENODEV;
+ }
+
+ }
+
+ if ( uiRetries != 0 )
+ {
+ /* Clear the ones that are set - either, Empty/Full/Avail bits */
+ value = ( uiStatus & ( EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL ) );
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+ }
+
+ /* Here we should check if the EEPROM status register is correct before
+ * proceeding. Bit 0 in the EEPROM Status register should be 0 before
+ * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy
+ * with the previous write. Note also that issuing this read finally
+ * means the previous write to the EEPROM has completed. */
+ uiRetries = MAX_EEPROM_RETRIES*RETRIES_PER_DELAY;
+ uiEpromStatus = 0;
+ while ( uiRetries != 0 )
+ {
+ uiEpromStatus = ReadEEPROMStatusRegister( Adapter) ;
+ if(Adapter->device_removed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
+ return -ENODEV;
+ }
+ if ( ( EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus ) == 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY- uiRetries) );
+ return STATUS_SUCCESS ;
+ }
+ uiRetries--;
+ if ( uiRetries == 0 )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES *RETRIES_PER_DELAY);
+ return STATUS_FAILURE ;
+ }
+ uiEpromStatus = 0;
+ if( !(uiRetries%RETRIES_PER_DELAY) )
+ msleep(1);
+ }
+
+ return STATUS_SUCCESS ;
+} /* BeceemEEPROMWritePage */
+
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemEEPROMBulkWrite
+//
+// Description: Performs write to the EEPROM
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Data to be written.
+// uiOffset - Offset of the EEPROM where data needs to be written to.
+// uiNumBytes - Number of bytes to be written.
+// bVerify - read verify flag.
+// Returns:
+// OSAL_STATUS_CODE
+//
+//-----------------------------------------------------------------------------
+
+INT BeceemEEPROMBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUCHAR pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify)
+{
+ UINT uiBytesToCopy = uiNumBytes;
+ //UINT uiRdbk = 0;
+ UINT uiData[4] = {0};
+ UINT uiIndex = 0;
+ UINT uiTempOffset = 0;
+ UINT uiExtraBytes = 0;
+ //PUINT puiBuffer = (PUINT)pBuffer;
+ //INT value;
+
+ if(uiOffset%MAX_RW_SIZE && uiBytesToCopy)
+ {
+ uiTempOffset = uiOffset - (uiOffset%MAX_RW_SIZE);
+ uiExtraBytes = uiOffset-uiTempOffset;
+
+
+ BeceemEEPROMBulkRead(Adapter,&uiData[0],uiTempOffset,MAX_RW_SIZE);
+
+ if(uiBytesToCopy >= (16 -uiExtraBytes))
+ {
+ OsalMemMove((((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
+ {
+ OsalMemMove((((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);
+ OsalMemMove(&uiData[0],pBuffer+uiIndex,uiBytesToCopy);
+
+
+ if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiOffset ) )
+ return STATUS_FAILURE;
+ uiBytesToCopy = 0;
+ }
+
+ }
+
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemNVMRead
+//
+// Description: Reads n number of bytes from NVM.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Buffer to store the data read from NVM
+// uiOffset - Offset of NVM from where data should be read
+// uiNumBytes - Number of bytes to be read from the NVM.
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if NVM read is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BeceemNVMRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes)
+{
+ INT Status = 0;
+#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
+ UINT uiTemp = 0, value;
+#endif
+
+ if(Adapter->eNVMType == NVM_FLASH)
+ {
+ if(Adapter->bFlashRawRead == FALSE)
+ {
+ if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
+ return vendorextnReadSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes);
+ uiOffset = uiOffset+ Adapter->ulFlashCalStart ;
+ }
+#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
+ Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes);
+#else
+
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+ Status = BeceemFlashBulkRead(Adapter,
+ pBuffer,
+ uiOffset,
+ uiNumBytes);
+ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+#endif
+ }
+ else if(Adapter->eNVMType == NVM_EEPROM)
+ {
+ Status = BeceemEEPROMBulkRead(Adapter,
+ pBuffer,
+ uiOffset,
+ uiNumBytes);
+ }
+ else
+ {
+ Status = -1;
+ }
+ return Status;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BeceemNVMWrite
+//
+// Description: Writes n number of bytes to NVM.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// pBuffer - Buffer contains the data to be written.
+// uiOffset - Offset of NVM where data to be written to.
+// uiNumBytes - Number of bytes to be written..
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if NVM write is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BeceemNVMWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ BOOLEAN bVerify)
+{
+ INT Status = 0;
+ UINT uiTemp = 0;
+ UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
+ UINT uiIndex = 0;
+#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
+ UINT value;
+#endif
+ UINT uiFlashOffset = 0;
+
+ if(Adapter->eNVMType == NVM_FLASH)
+ {
+ if (IsSectionExistInVendorInfo(Adapter,Adapter->eActiveDSD))
+ Status = vendorextnWriteSection(Adapter,(PUCHAR)pBuffer,Adapter->eActiveDSD,uiOffset,uiNumBytes,bVerify);
+ else
+ {
+ uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;
+
+#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
+ Status = bcmflash_raw_write((uiFlashOffset/FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer,uiNumBytes);
+#else
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
+
+ if(Adapter->bStatusWrite == TRUE)
+ {
+ Status = BeceemFlashBulkWriteStatus(Adapter,
+ pBuffer,
+ uiFlashOffset,
+ uiNumBytes ,
+ bVerify);
+ }
+ else
+ {
+
+ Status = BeceemFlashBulkWrite(Adapter,
+ pBuffer,
+ uiFlashOffset,
+ uiNumBytes,
+ bVerify);
+ }
+#endif
+ }
+
+
+ if(uiOffset >= EEPROM_CALPARAM_START)
+ {
+ uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
+ while(uiNumBytes)
+ {
+ if(uiNumBytes > BUFFER_4K)
+ {
+ wrm(Adapter,(uiMemoryLoc+uiIndex),(PCHAR)(pBuffer+(uiIndex/4)),BUFFER_4K);
+ uiNumBytes -= BUFFER_4K;
+ uiIndex += BUFFER_4K;
+ }
+ else
+ {
+ wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)(pBuffer+(uiIndex/4)),uiNumBytes);
+ uiNumBytes = 0;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if((uiOffset+uiNumBytes) > EEPROM_CALPARAM_START)
+ {
+ ULONG ulBytesTobeSkipped = 0;
+ PUCHAR pcBuffer = (PUCHAR)pBuffer;// char pointer to take care of odd byte cases.
+ uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
+ ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
+ uiOffset += (EEPROM_CALPARAM_START - uiOffset);
+ while(uiNumBytes)
+ {
+ if(uiNumBytes > BUFFER_4K)
+ {
+ wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR )&pcBuffer[ulBytesTobeSkipped+uiIndex],BUFFER_4K);
+ uiNumBytes -= BUFFER_4K;
+ uiIndex += BUFFER_4K;
+ }
+ else
+ {
+ wrm(Adapter,uiMemoryLoc+uiIndex,(PCHAR)&pcBuffer[ulBytesTobeSkipped+uiIndex],uiNumBytes);
+ uiNumBytes = 0;
+ break;
+ }
+ }
+
+ }
+ }
+
+ // restore the values.
+ wrmalt(Adapter,0x0f000C80,&uiTemp, sizeof(uiTemp));
+ }
+ else if(Adapter->eNVMType == NVM_EEPROM)
+ {
+ Status = BeceemEEPROMBulkWrite(Adapter,
+ (PUCHAR)pBuffer,
+ uiOffset,
+ uiNumBytes,
+ bVerify);
+ if(bVerify)
+ {
+ Status = BeceemEEPROMReadBackandVerify(Adapter,(PUINT)pBuffer,uiOffset,uiNumBytes);
+ }
+ }
+ else
+ {
+ Status = -1;
+ }
+ return Status;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmUpdateSectorSize
+//
+// Description: Updates the sector size to FLASH.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+// uiSectorSize - sector size
+//
+// Returns:
+// OSAL_STATUS_SUCCESS - if NVM write is successfull.
+// <FAILURE> - if failed.
+//-----------------------------------------------------------------------------
+
+INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize)
+{
+ INT Status = -1;
+ FLASH_CS_INFO sFlashCsInfo = {0};
+ UINT uiTemp = 0;
+
+ UINT uiSectorSig = 0;
+ UINT uiCurrentSectorSize = 0;
+
+ UINT value;
+
+
+
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+
+//
+// Before updating the sector size in the reserved area, check if already present.
+//
+ BeceemFlashBulkRead(Adapter,(PUINT)&sFlashCsInfo,Adapter->ulFlashControlSectionStart,sizeof(sFlashCsInfo));
+ uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
+ uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);
+
+ if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
+ {
+
+ if((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE))
+ {
+ if(uiSectorSize == uiCurrentSectorSize)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Provided sector size is same as programmed in Flash");
+ Status = STATUS_SUCCESS;
+ goto Restore ;
+ }
+ }
+ }
+
+ if((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE))
+ {
+
+ sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize);
+ sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG);
+
+ Status = BeceemFlashBulkWrite(Adapter,
+ (PUINT)&sFlashCsInfo,
+ Adapter->ulFlashControlSectionStart,
+ sizeof(sFlashCsInfo),
+ TRUE);
+
+
+ }
+
+ Restore :
+ // restore the values.
+ wrmalt(Adapter, 0x0f000C80,&uiTemp, sizeof(uiTemp));
+
+
+ return Status;
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetFlashSectorSize
+//
+// Description: Finds the sector size of the FLASH.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// UINT - sector size.
+//
+//-----------------------------------------------------------------------------
+
+UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize)
+{
+ UINT uiSectorSize = 0;
+ UINT uiSectorSig = 0;
+
+ if(Adapter->bSectorSizeOverride &&
+ (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
+ Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE))
+ {
+ Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
+ }
+ else
+ {
+
+ uiSectorSig = FlashSectorSizeSig;
+
+ if(uiSectorSig == FLASH_SECTOR_SIZE_SIG)
+ {
+ uiSectorSize = FlashSectorSize;
+ //
+ // If the sector size stored in the FLASH makes sense then use it.
+ //
+ if(uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE)
+ {
+ Adapter->uiSectorSize = uiSectorSize;
+ }
+ //No valid size in FLASH, check if Config file has it.
+ else if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
+ Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
+ {
+ Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
+ }
+ // Init to Default, if none of the above works.
+ else
+ {
+ Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
+ }
+
+ }
+ else
+ {
+ if(Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
+ Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
+ {
+ Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
+ }
+ else
+ {
+ Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
+ }
+ }
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x \n", Adapter->uiSectorSize);
+ return Adapter->uiSectorSize;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmInitEEPROMQueues
+//
+// Description: Initialization of EEPROM queues.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// <OSAL_STATUS_CODE>
+//-----------------------------------------------------------------------------
+
+static INT BcmInitEEPROMQueues(PMINI_ADAPTER Adapter)
+{
+ UINT value = 0;
+ /* CHIP Bug : Clear the Avail bits on the Read queue. The default
+ * value on this register is supposed to be 0x00001102.
+ * But we get 0x00001122. */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Fixing reset value on 0x0f003004 register\n" );
+ value = EEPROM_READ_DATA_AVAIL;
+ wrmalt( Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
+
+ /* Flush the all the EEPROM queues. */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n");
+ value =EEPROM_ALL_QUEUE_FLUSH ;
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value));
+
+ value = 0;
+ wrmalt( Adapter, SPI_FLUSH_REG, &value, sizeof(value) );
+
+ /* Read the EEPROM Status Register. Just to see, no real purpose. */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter) );
+
+ return STATUS_SUCCESS;
+} /* BcmInitEEPROMQueues() */
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmInitNVM
+//
+// Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// <OSAL_STATUS_CODE>
+//-----------------------------------------------------------------------------
+
+INT BcmInitNVM(PMINI_ADAPTER ps_adapter)
+{
+#ifdef BCM_SHM_INTERFACE
+#ifdef FLASH_DIRECT_ACCESS
+ unsigned int data,data1,data2 = 1;
+ wrm(ps_adapter, PAD_SELECT_REGISTER, &data2, 4);
+ data1 = rdm(ps_adapter,SYS_CFG,&data,4);
+ data1 = rdm(ps_adapter,SYS_CFG,&data,4);
+ data2 = (data | 0x80 | 0x8000);
+ wrm(ps_adapter,SYS_CFG, &data2,4); // over-write as Flash boot mode
+#endif
+ ps_adapter->eNVMType = NVM_FLASH;
+#else
+ BcmValidateNvmType(ps_adapter);
+ BcmInitEEPROMQueues(ps_adapter);
+#endif
+
+ if(ps_adapter->eNVMType == NVM_AUTODETECT)
+ {
+ ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
+ if(ps_adapter->eNVMType == NVM_UNKNOWN)
+ {
+ BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
+ }
+ }
+ else if(ps_adapter->eNVMType == NVM_FLASH)
+ {
+ BcmGetFlashCSInfo(ps_adapter);
+ }
+
+ BcmGetNvmSize(ps_adapter);
+
+ return STATUS_SUCCESS;
+}
+/***************************************************************************/
+/*BcmGetNvmSize : set the EEPROM or flash size in Adapter.
+*
+*Input Parameter:
+* Adapter data structure
+*Return Value :
+* 0. means sucess;
+*/
+/***************************************************************************/
+
+INT BcmGetNvmSize(PMINI_ADAPTER Adapter)
+{
+ if(Adapter->eNVMType == NVM_EEPROM)
+ {
+ Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
+ }
+ else if(Adapter->eNVMType == NVM_FLASH)
+ {
+ Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
+ }
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmValidateNvm
+//
+// Description: Validates the NVM Type option selected against the device
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// <VOID>
+//-----------------------------------------------------------------------------
+VOID BcmValidateNvmType(PMINI_ADAPTER Adapter)
+{
+
+ //
+ // if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
+ // Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
+ // So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
+ //
+
+ if(Adapter->eNVMType == NVM_FLASH &&
+ Adapter->chip_id < 0xBECE3300)
+ {
+ Adapter->eNVMType = NVM_AUTODETECT;
+ }
+}
+//-----------------------------------------------------------------------------
+// Procedure: BcmReadFlashRDID
+//
+// Description: Reads ID from Serial Flash
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// Flash ID
+//-----------------------------------------------------------------------------
+static ULONG BcmReadFlashRDID(PMINI_ADAPTER Adapter)
+{
+ ULONG ulRDID = 0;
+ UINT value;
+//
+// Read ID Instruction.
+//
+ value = (FLASH_CMD_READ_ID<<24);
+ wrmalt(Adapter, FLASH_SPI_CMDQ_REG,&value, sizeof(value));
+
+//Delay
+ udelay(10);
+//
+// Read SPI READQ REG. The output will be WWXXYYZZ.
+// The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
+//
+ rdmalt(Adapter, FLASH_SPI_READQ_REG,(PUINT)&ulRDID, sizeof(ulRDID));
+
+ return (ulRDID >>8);
+
+
+}
+
+INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
+{
+ if(psAdapter == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
+ return -EINVAL;
+ }
+ psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL);
+ if(psAdapter->psFlashCSInfo == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 1.x");
+ return -ENOMEM;
+ }
+
+ psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL);
+ if(psAdapter->psFlash2xCSInfo == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x");
+ bcm_kfree(psAdapter->psFlashCSInfo);
+ return -ENOMEM;
+ }
+
+ psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL);
+ if(psAdapter->psFlash2xVendorInfo == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x");
+ bcm_kfree(psAdapter->psFlashCSInfo);
+ bcm_kfree(psAdapter->psFlash2xCSInfo);
+ return -ENOMEM;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter)
+{
+ if(psAdapter == NULL)
+ {
+ BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL");
+ return -EINVAL;
+ }
+ bcm_kfree(psAdapter->psFlashCSInfo);
+ bcm_kfree(psAdapter->psFlash2xCSInfo);
+ bcm_kfree(psAdapter->psFlash2xVendorInfo);
+ return STATUS_SUCCESS ;
+}
+
+static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo,PMINI_ADAPTER Adapter)
+{
+ UINT Index = 0;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware ));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
+ for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
+ (psFlash2xCSInfo->SectorAccessBitMap[Index]));
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo)
+{
+ UINT Index = 0;
+ psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
+ psFlash2xCSInfo->FlashLayoutVersion= ntohl(psFlash2xCSInfo->FlashLayoutVersion);
+ //psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion);
+ psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
+ psFlash2xCSInfo->SCSIFirmwareVersion =ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
+ psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
+ psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
+ psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware );
+ psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
+ psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
+ psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
+ psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
+ psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
+ psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
+ psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
+ psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
+ psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
+ psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
+ psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
+ psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
+ psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
+ psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
+ psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
+ psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
+ psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
+ psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
+ psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
+ psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
+ psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
+ psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
+ psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
+ psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
+ psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
+ psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
+ psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
+ psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
+ psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
+ psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
+ psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
+ psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
+ psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
+ psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
+ psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
+ psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
+ psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
+ psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
+ for(Index =0; Index <(FLASH2X_TOTAL_SIZE/(DEFAULT_SECTOR_SIZE *16)); Index++)
+ {
+ psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
+ }
+ return STATUS_SUCCESS;
+}
+
+static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo)
+{
+ //UINT Index = 0;
+ psFlashCSInfo->MagicNumber =ntohl(psFlashCSInfo->MagicNumber);
+ psFlashCSInfo->FlashLayoutVersion =ntohl(psFlashCSInfo->FlashLayoutVersion);
+ psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion);
+ //won't convert according to old assumption
+ psFlashCSInfo->SCSIFirmwareVersion =(psFlashCSInfo->SCSIFirmwareVersion);
+
+ psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
+ psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
+ psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware );
+ psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
+ psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
+ psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
+ psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
+ psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
+ psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
+ psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
+ psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout);
+ psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature);
+ psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig);
+ psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize);
+ psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize);
+ psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize);
+ psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr);
+ psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize);
+ psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
+ psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout);
+
+ return STATUS_SUCCESS;
+}
+
+INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
+{
+ return ( Adapter->uiVendorExtnFlag &&
+ (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
+ (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS) );
+}
+
+static VOID UpdateVendorInfo(PMINI_ADAPTER Adapter)
+{
+ B_UINT32 i = 0;
+ UINT uiSizeSection = 0;
+
+ Adapter->uiVendorExtnFlag = FALSE;
+
+ for(i = 0;i < TOTAL_SECTIONS;i++)
+ Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
+
+ if(STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
+ return;
+
+ i = 0;
+ while(i < TOTAL_SECTIONS)
+ {
+ if(!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT))
+ {
+ i++;
+ continue;
+ }
+
+ Adapter->uiVendorExtnFlag = TRUE;
+ uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
+ Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
+
+ switch(i)
+ {
+ case DSD0:
+ if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
+ (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
+ break;
+
+ case DSD1:
+ if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
+ (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
+ break;
+
+ case DSD2:
+ if(( uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER))) &&
+ (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
+ break;
+ case VSA0:
+ if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
+ break;
+
+ case VSA1:
+ if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
+ break;
+ case VSA2:
+ if(UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
+ else
+ Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
+ break;
+
+ default:
+ break;
+ }
+ i++;
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetFlashCSInfo
+//
+// Description: Reads control structure and gets Cal section addresses.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// <VOID>
+//-----------------------------------------------------------------------------
+
+INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter)
+{
+ //FLASH_CS_INFO sFlashCsInfo = {0};
+
+#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
+ UINT value;
+#endif
+ UINT uiFlashLayoutMajorVersion;
+ Adapter->uiFlashLayoutMinorVersion = 0;
+ Adapter->uiFlashLayoutMajorVersion = 0;
+ Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
+
+
+ Adapter->uiFlashBaseAdd = 0;
+ Adapter->ulFlashCalStart = 0;
+ memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO));
+ memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO));
+
+#ifndef BCM_SHM_INTERFACE
+ if(!Adapter->bDDRInitDone)
+ {
+ {
+ value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
+ wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
+ }
+ }
+
+#endif
+
+ // 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);
+#ifndef BCM_SHM_INTERFACE
+ BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter);
+#endif
+ 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 ????
+ */
+#ifndef BCM_SHM_INTERFACE
+ Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
+#endif
+
+ Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
+
+ #if 0
+ if(FLASH_PART_SST25VF080B == Adapter->ulFlashID)
+ {
+ //
+ // 1MB flash has been selected. we have to use 64K as sector size no matter what is kept in FLASH_CS.
+ //
+ Adapter->uiSectorSize = 0x10000;
+ }
+ #endif
+
+ return STATUS_SUCCESS ;
+}
+
+
+//-----------------------------------------------------------------------------
+// Procedure: BcmGetNvmType
+//
+// Description: Finds the type of NVM used.
+//
+// Arguments:
+// Adapter - ptr to Adapter object instance
+//
+// Returns:
+// NVM_TYPE
+//
+//-----------------------------------------------------------------------------
+
+NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter)
+{
+ UINT uiData = 0;
+
+ BeceemEEPROMBulkRead(Adapter,&uiData,0x0,4);
+ if(uiData == BECM)
+ {
+ return NVM_EEPROM;
+ }
+ //
+ // Read control struct and get cal addresses before accessing the flash
+ //
+ BcmGetFlashCSInfo(Adapter);
+
+ BeceemFlashBulkRead(Adapter,&uiData,0x0 + Adapter->ulFlashCalStart,4);
+ if(uiData == BECM)
+ {
+ return NVM_FLASH;
+ }
+//
+// even if there is no valid signature on EEPROM/FLASH find out if they really exist.
+// if exist select it.
+//
+ if(BcmGetEEPROMSize(Adapter))
+ {
+ return NVM_EEPROM;
+ }
+
+//TBD for Flash.
+
+
+ return NVM_UNKNOWN;
+}
+
+/**
+* BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
+* @Adapter : Drivers Private Data structure
+* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
+*
+* Return value:-
+* On success it return the start offset of the provided section val
+* On Failure -returns STATUS_FAILURE
+**/
+
+INT BcmGetSectionValStartOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
+{
+ /*
+ * Considering all the section for which end offset can be calculated or directly given
+ * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
+ * endoffset can't be calculated or given in CS Stucture.
+ */
+
+ INT SectStartOffset = 0 ;
+
+ SectStartOffset = INVALID_OFFSET ;
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlashSectionVal))
+ {
+ return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
+ }
+
+ switch(eFlashSectionVal)
+ {
+ case ISO_IMAGE1 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
+ break;
+ case ISO_IMAGE2 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
+ break;
+ case DSD0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
+ break;
+ case DSD1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
+ break;
+ case DSD2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
+ break;
+ case VSA0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
+ break;
+ case VSA1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
+ break;
+ case VSA2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
+ break;
+ case SCSI :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
+ break;
+ case CONTROL_SECTION :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
+ break;
+ case ISO_IMAGE1_PART2 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
+ break;
+ case ISO_IMAGE1_PART3 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
+ break;
+ case ISO_IMAGE2_PART2 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
+ break;
+ case ISO_IMAGE2_PART3 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
+ SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
+ break;
+ default :
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
+ SectStartOffset = INVALID_OFFSET;
+ }
+ return SectStartOffset;
+}
+
+/**
+* BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
+* @Adapter : Drivers Private Data structure
+* @eFlashSectionVal : Flash secion value defined in enum FLASH2X_SECTION_VAL
+*
+* Return value:-
+* On success it return the end offset of the provided section val
+* On Failure -returns STATUS_FAILURE
+**/
+
+INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+{
+ INT SectEndOffset = 0 ;
+ SectEndOffset = INVALID_OFFSET;
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
+ {
+ return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
+ }
+
+ switch(eFlash2xSectionVal)
+ {
+ case ISO_IMAGE1 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End!= UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
+ break;
+ case ISO_IMAGE2 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End!= UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
+ break;
+ case DSD0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
+ break;
+ case DSD1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
+ break;
+ case DSD2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
+ break;
+ case VSA0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
+ break;
+ case VSA1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
+ break;
+ case VSA2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
+ break;
+ case SCSI :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
+ SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
+ (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
+ break;
+ case CONTROL_SECTION :
+ //Not Clear So Putting failure. confirm and fix it.
+ SectEndOffset = STATUS_FAILURE;
+ case ISO_IMAGE1_PART2 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End!= UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
+ break;
+ case ISO_IMAGE1_PART3 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End!= UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
+ break;
+ case ISO_IMAGE2_PART2 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
+ break;
+ case ISO_IMAGE2_PART3 :
+ if(Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End!= UNINIT_PTR_IN_CS)
+ SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
+ break;
+
+ default :
+ SectEndOffset = INVALID_OFFSET;
+ }
+ return SectEndOffset ;
+}
+
+/*
+* BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
+* @Adapter :Driver Private Data Structure
+* @pBuffer : Buffer where data has to be put after reading
+* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
+* @uiOffsetWithinSectionVal :- Offset with in provided section
+* @uiNumBytes : Number of Bytes for Read
+*
+* Return value:-
+* return true on sucess and STATUS_FAILURE on fail.
+*/
+
+INT BcmFlash2xBulkRead(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ FLASH2X_SECTION_VAL eFlash2xSectionVal,
+ UINT uiOffsetWithinSectionVal,
+ UINT uiNumBytes)
+{
+
+ INT Status = STATUS_SUCCESS;
+ INT SectionStartOffset = 0;
+ UINT uiAbsoluteOffset = 0 ;
+ UINT uiTemp =0, value =0 ;
+ if(Adapter == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
+ return -EINVAL;
+ }
+ if(Adapter->device_removed )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
+ return -ENODEV;
+ }
+
+ //NO_SECTION_VAL means absolute offset is given.
+ if(eFlash2xSectionVal == NO_SECTION_VAL)
+ SectionStartOffset = 0;
+ else
+ SectionStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
+
+ if(SectionStartOffset == STATUS_FAILURE )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash 2.x Map ",eFlash2xSectionVal);
+ return -EINVAL;
+ }
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
+ return vendorextnReadSection(Adapter,(PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
+
+ //calculating the absolute offset from FLASH;
+ uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+
+ Status= BeceemFlashBulkRead(Adapter, pBuffer,uiAbsoluteOffset,uiNumBytes) ;
+
+ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
+ return Status ;
+ }
+
+ return Status;
+}
+
+/*
+* BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
+* @Adapter :Driver Private Data Structure
+* @pBuffer : Buffer From where data has to taken for writing
+* @eFlashSectionVal :Flash Section Val defined in FLASH2X_SECTION_VAL
+* @uiOffsetWithinSectionVal :- Offset with in provided section
+* @uiNumBytes : Number of Bytes for Write
+*
+* Return value:-
+* return true on sucess and STATUS_FAILURE on fail.
+*
+*/
+
+INT BcmFlash2xBulkWrite(
+ PMINI_ADAPTER Adapter,
+ PUINT pBuffer,
+ FLASH2X_SECTION_VAL eFlash2xSectVal,
+ UINT uiOffset,
+ UINT uiNumBytes,
+ UINT bVerify)
+{
+
+ INT Status = STATUS_SUCCESS;
+ UINT FlashSectValStartOffset = 0;
+ UINT uiTemp = 0, value = 0;
+ if(Adapter == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
+ return -EINVAL;
+ }
+ if(Adapter->device_removed )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
+ return -ENODEV;
+ }
+
+ //NO_SECTION_VAL means absolute offset is given.
+ if(eFlash2xSectVal == NO_SECTION_VAL)
+ FlashSectValStartOffset = 0;
+ else
+ FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectVal);
+
+ if(FlashSectValStartOffset == STATUS_FAILURE )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"This Section<%d> does not exixt in Flash Map 2.x",eFlash2xSectVal);
+ return -EINVAL;
+ }
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectVal))
+ return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
+
+ //calculating the absolute offset from FLASH;
+ uiOffset = uiOffset + FlashSectValStartOffset;
+
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+
+ Status = BeceemFlashBulkWrite(Adapter, pBuffer,uiOffset,uiNumBytes,bVerify);
+
+ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
+ return Status ;
+ }
+
+ return Status;
+
+}
+
+/**
+* ReadDSDHeader : Read the DSD map for the DSD Section val provided in Argument.
+* @Adapter : Beceem Private Data Structure
+* @psDSDHeader :Pointer of the buffer where header has to be read
+* @dsd :value of the Dyanmic DSD like DSD0 of DSD1 or DSD2
+*
+* Return Value:-
+* if suceeds return STATUS_SUCCESS or negative error code.
+**/
+INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd)
+{
+ INT Status = STATUS_SUCCESS;
+
+ Status =BcmFlash2xBulkRead(Adapter,
+ (PUINT)psDSDHeader,
+ dsd,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader,
+ sizeof(DSD_HEADER));
+ if(Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageMagicNumber :0X%x", ntohl(psDSDHeader->DSDImageMagicNumber));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageSize :0X%x ",ntohl(psDSDHeader->DSDImageSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageCRC :0X%x",ntohl(psDSDHeader->DSDImageCRC));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImagePriority :0X%x",ntohl(psDSDHeader->DSDImagePriority));
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DSD Header read is failed with status :%d", Status);
+ }
+
+ return Status;
+}
+
+/**
+* BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
+* @Adapter :-Drivers private Data Structure
+*
+* Return Value:-
+* Return STATUS_SUCESS if get sucess in setting the right DSD else negaive error code
+*
+**/
+INT BcmGetActiveDSD(PMINI_ADAPTER Adapter)
+{
+ FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
+
+ uiHighestPriDSD = getHighestPriDSD(Adapter);
+ Adapter->eActiveDSD = uiHighestPriDSD;
+
+ if(DSD0 == uiHighestPriDSD)
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
+ if(DSD1 == uiHighestPriDSD)
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
+ if(DSD2 == uiHighestPriDSD)
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
+ if(Adapter->eActiveDSD)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
+ if(Adapter->eActiveDSD == 0)
+ {
+ //if No DSD gets Active, Make Active the DSD with WR permission
+ if(IsSectionWritable(Adapter,DSD2))
+ {
+ Adapter->eActiveDSD = DSD2;
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
+ }
+ else if(IsSectionWritable(Adapter,DSD1))
+ {
+ Adapter->eActiveDSD = DSD1;
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
+ }
+ else if(IsSectionWritable(Adapter,DSD0))
+ {
+ Adapter->eActiveDSD = DSD0;
+ Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+/**
+* ReadISOUnReservedBytes : Read the ISO map for the ISO Section val provided in Argument.
+* @Adapter : Driver Private Data Structure
+* @psISOHeader :Pointer of the location where header has to be read
+* @IsoImage :value of the Dyanmic ISO like ISO_IMAGE1 of ISO_IMAGE2
+*
+* Return Value:-
+* if suceeds return STATUS_SUCCESS or negative error code.
+**/
+
+INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage)
+{
+ INT Status = STATUS_SUCCESS;
+
+ Status = BcmFlash2xBulkRead(Adapter,
+ (PUINT)psISOHeader,
+ IsoImage,
+ 0,
+ sizeof(ISO_HEADER));
+
+ if(Status == STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageMagicNumber :0X%x", ntohl(psISOHeader->ISOImageMagicNumber));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageSize :0X%x ",ntohl(psISOHeader->ISOImageSize));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageCRC :0X%x",ntohl(psISOHeader->ISOImageCRC));
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImagePriority :0X%x",ntohl(psISOHeader->ISOImagePriority));
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ISO Header Read failed");
+ }
+ return Status;
+}
+
+/**
+* BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
+* @Adapter : Driver private Data Structure
+*
+* Return Value:-
+* Sucsess:- STATUS_SUCESS
+* Failure- : negative erro code
+*
+**/
+
+INT BcmGetActiveISO(PMINI_ADAPTER Adapter)
+{
+
+ INT HighestPriISO = 0 ;
+ HighestPriISO = getHighestPriISO(Adapter);
+
+ Adapter->eActiveISO = HighestPriISO ;
+ if(Adapter->eActiveISO == ISO_IMAGE2)
+ Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
+ else if(Adapter->eActiveISO == ISO_IMAGE1)
+ Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
+
+ if(Adapter->eActiveISO)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Active ISO :%x", Adapter->eActiveISO);
+
+ return STATUS_SUCCESS;
+}
+
+/**
+* IsOffsetWritable :- it will tell the access permission of the sector having passed offset
+* @Adapter : Drivers Private Data Structure
+* @uiOffset : Offset provided in the Flash
+*
+* Return Value:-
+* Sucess:-TRUE , offset is writable
+* Failure:-FALSE, offset is RO
+*
+**/
+B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset)
+{
+ UINT uiSectorNum = 0;
+ UINT uiWordOfSectorPermission =0;
+ UINT uiBitofSectorePermission = 0;
+ B_UINT32 permissionBits = 0;
+ uiSectorNum = uiOffset/Adapter->uiSectorSize;
+
+ //calculating the word having this Sector Access permission from SectorAccessBitMap Array
+ uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum /16];
+
+ //calculating the bit index inside the word for this sector
+ uiBitofSectorePermission = 2*(15 - uiSectorNum %16);
+
+ //Setting Access permission
+ permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission) ;
+ permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
+ if(permissionBits == SECTOR_READWRITE_PERMISSION)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
+{
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD0 :0X%x", psFlash2xBitMap->DSD0);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD1 :0X%x", psFlash2xBitMap->DSD1);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD2 :0X%x", psFlash2xBitMap->DSD2);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA0 :0X%x", psFlash2xBitMap->VSA0);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA1 :0X%x", psFlash2xBitMap->VSA1);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"VSA2 :0X%x", psFlash2xBitMap->VSA2);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"SCSI :0X%x", psFlash2xBitMap->SCSI);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION);
+
+ return STATUS_SUCCESS;
+}
+
+/**
+* BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
+* 8bit has been assigned to every section.
+ bit[0] :Section present or not
+ bit[1] :section is valid or not
+ bit[2] : Secton is read only or has write permission too.
+ bit[3] : Active Section -
+ bit[7...4] = Reserved .
+
+ @Adapter:-Driver private Data Structure
+*
+* Return value:-
+* Sucess:- STATUS_SUCESS
+* Failure:- negative error code
+**/
+
+INT BcmGetFlash2xSectionalBitMap(PMINI_ADAPTER Adapter, PFLASH2X_BITMAP psFlash2xBitMap)
+{
+
+
+ PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
+ FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ;
+ FLASH2X_SECTION_VAL uiHighestPriISO= 0 ;
+ BOOLEAN SetActiveDSDDone = FALSE ;
+ BOOLEAN SetActiveISODone = FALSE ;
+
+ //For 1.x map all the section except DSD0 will be shown as not present
+ //This part will be used by calibration tool to detect the number of DSD present in Flash.
+ if(IsFlash2x(Adapter) == FALSE)
+ {
+ psFlash2xBitMap->ISO_IMAGE2 = 0;
+ psFlash2xBitMap->ISO_IMAGE1 = 0;
+ psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; //0xF; //0000(Reseved)1(Active)0(RW)1(valid)1(present)
+ psFlash2xBitMap->DSD1 = 0 ;
+ psFlash2xBitMap->DSD2 = 0 ;
+ psFlash2xBitMap->VSA0 = 0 ;
+ psFlash2xBitMap->VSA1 = 0 ;
+ psFlash2xBitMap->VSA2 = 0 ;
+ psFlash2xBitMap->CONTROL_SECTION = 0 ;
+ psFlash2xBitMap->SCSI= 0 ;
+ psFlash2xBitMap->Reserved0 = 0 ;
+ psFlash2xBitMap->Reserved1 = 0 ;
+ psFlash2xBitMap->Reserved2 = 0 ;
+ return STATUS_SUCCESS ;
+
+ }
+
+ uiHighestPriDSD = getHighestPriDSD(Adapter);
+ uiHighestPriISO = getHighestPriISO(Adapter);
+
+ ///
+ // IS0 IMAGE 2
+ ///
+ if((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->ISO_IMAGE2= psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
+
+
+ if(ReadISOSignature(Adapter,ISO_IMAGE2)== ISO_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
+
+
+ //Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
+ psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
+
+ if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2)
+ {
+ psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT ;
+ SetActiveISODone = TRUE;
+ }
+
+ }
+
+ ///
+ // IS0 IMAGE 1
+ ///
+ if((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
+
+ if(ReadISOSignature(Adapter,ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
+
+ // Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
+ psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
+
+ if(SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1)
+ {
+ psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT ;
+ SetActiveISODone = TRUE;
+ }
+ }
+
+
+
+ ///
+ // DSD2
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->DSD2= psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
+
+ if(ReadDSDSignature(Adapter,DSD2)== DSD_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
+
+ //Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, DSD2) == FALSE)
+ {
+ psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
+
+ }
+ else
+ {
+ //Means section is writable
+ if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2))
+ {
+ psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT ;
+ SetActiveDSDDone =TRUE ;
+ }
+ }
+ }
+
+ ///
+ // DSD 1
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->DSD1= psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
+
+
+ if(ReadDSDSignature(Adapter,DSD1)== DSD_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
+
+ //Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, DSD1) == FALSE)
+ {
+ psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
+ }
+ else
+ {
+ //Means section is writable
+ if((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1))
+ {
+ psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT ;
+ SetActiveDSDDone =TRUE ;
+ }
+ }
+
+ }
+
+ ///
+ //For DSD 0
+ //
+ if((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
+
+ if(ReadDSDSignature(Adapter,DSD0) == DSD_IMAGE_MAGIC_NUMBER)
+ psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
+
+ //Setting Access permission
+ if(IsSectionWritable(Adapter, DSD0) == FALSE)
+ {
+ psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
+ }
+ else
+ {
+ //Means section is writable
+ if((SetActiveDSDDone == FALSE) &&(uiHighestPriDSD == DSD0))
+ {
+ psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT ;
+ SetActiveDSDDone =TRUE ;
+ }
+ }
+ }
+
+ ///
+ // VSA 0
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->VSA0= psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
+
+ //Calculation for extrating the Access permission
+ if(IsSectionWritable(Adapter, VSA0) == FALSE)
+ psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT ;
+
+ }
+
+
+ ///
+ // VSA 1
+ ///
+
+ if((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->VSA1= psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->VSA1|= FLASH2X_SECTION_VALID;
+
+ //Checking For Access permission
+ if(IsSectionWritable(Adapter, VSA1) == FALSE)
+ psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT ;
+
+ }
+
+
+ ///
+ // VSA 2
+ ///
+
+ if((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->VSA2= psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
+
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
+
+ //Checking For Access permission
+ if(IsSectionWritable(Adapter, VSA2) == FALSE)
+ psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT ;
+ }
+
+ ///
+ // SCSI Section
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->SCSI= psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
+
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->SCSI|= FLASH2X_SECTION_VALID;
+
+ //Checking For Access permission
+ if(IsSectionWritable(Adapter, SCSI) == FALSE)
+ psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT ;
+
+ }
+
+
+ ///
+ // Control Section
+ ///
+ if((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS)
+ {
+ //Setting the 0th Bit representing the Section is present or not.
+ psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
+
+
+ //Setting the Access Bit. Map is not defined hece setting it always valid
+ psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
+
+ //Checking For Access permission
+ if(IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
+ psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
+
+ //By Default section is Active
+ psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT ;
+
+ }
+
+ ///
+ // For Reserved Sections
+ ///
+ psFlash2xBitMap->Reserved0 = 0;
+ psFlash2xBitMap->Reserved0 = 0;
+ psFlash2xBitMap->Reserved0 = 0;
+
+ BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
+
+ return STATUS_SUCCESS ;
+
+}
+/**
+BcmSetActiveSection :- Set Active section is used to make priority field highest over other
+ section of same type.
+
+@Adapater :- Bcm Driver Private Data Structure
+@eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
+
+Return Value:- Make the priorit highest else return erorr code
+
+**/
+INT BcmSetActiveSection(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal)
+{
+ unsigned int SectImagePriority = 0;
+ INT Status =STATUS_SUCCESS;
+
+ //DSD_HEADER sDSD = {0};
+ //ISO_HEADER sISO = {0};
+ INT HighestPriDSD = 0 ;
+ INT HighestPriISO = 0;
+
+
+
+ Status = IsSectionWritable(Adapter,eFlash2xSectVal) ;
+ if(Status != TRUE )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section <%d> is not writable",eFlash2xSectVal);
+ return STATUS_FAILURE;
+ }
+
+ Adapter->bHeaderChangeAllowed = TRUE ;
+ switch(eFlash2xSectVal)
+ {
+ case ISO_IMAGE1 :
+ case ISO_IMAGE2 :
+ if(ReadISOSignature(Adapter,eFlash2xSectVal)== ISO_IMAGE_MAGIC_NUMBER )
+ {
+ HighestPriISO = getHighestPriISO(Adapter);
+
+ if(HighestPriISO == eFlash2xSectVal )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal );
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+
+ SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
+
+ if((SectImagePriority <= 0) && IsSectionWritable(Adapter,HighestPriISO))
+ {
+ // This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
+ // We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
+ // by user
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
+ SectImagePriority = htonl(0x1);
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ HighestPriISO,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
+ SIGNATURE_SIZE,
+ TRUE);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
+ Status = STATUS_FAILURE;
+ break ;
+ }
+
+ HighestPriISO = getHighestPriISO(Adapter);
+
+ if(HighestPriISO == eFlash2xSectVal )
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given ISO<%x> already has highest priority",eFlash2xSectVal );
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+
+ SectImagePriority = 2;
+ }
+
+
+ SectImagePriority = htonl(SectImagePriority);
+
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ eFlash2xSectVal,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
+ SIGNATURE_SIZE,
+ TRUE);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
+ break ;
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
+ Status = STATUS_FAILURE ;
+ break;
+ }
+ break;
+ case DSD0 :
+ case DSD1 :
+ case DSD2 :
+ if(ReadDSDSignature(Adapter,eFlash2xSectVal)== DSD_IMAGE_MAGIC_NUMBER)
+ {
+ HighestPriDSD = getHighestPriDSD(Adapter);
+
+ if((HighestPriDSD == eFlash2xSectVal))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given DSD<%x> already has highest priority", eFlash2xSectVal);
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+
+ SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1 ;
+ if(SectImagePriority <= 0)
+ {
+ // This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
+ // We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
+ // by user
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happend, eFlash2xSectVal: 0x%x\n",eFlash2xSectVal);
+ SectImagePriority = htonl(0x1);
+
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ HighestPriDSD,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
+ SIGNATURE_SIZE,
+ TRUE);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
+ break ;
+ }
+
+ HighestPriDSD = getHighestPriDSD(Adapter);
+
+ if((HighestPriDSD == eFlash2xSectVal))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+
+ SectImagePriority = htonl(0x2);
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ HighestPriDSD,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
+ SIGNATURE_SIZE,
+ TRUE);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
+ break ;
+ }
+
+ HighestPriDSD = getHighestPriDSD(Adapter);
+
+ if((HighestPriDSD == eFlash2xSectVal))
+ {
+ Status = STATUS_SUCCESS ;
+ break;
+ }
+ SectImagePriority = 3 ;
+
+ }
+ SectImagePriority = htonl(SectImagePriority);
+ Status = BcmFlash2xBulkWrite(Adapter,
+ &SectImagePriority,
+ eFlash2xSectVal,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
+ SIGNATURE_SIZE ,
+ TRUE);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Priority has not been written properly");
+ Status = STATUS_FAILURE ;
+ break ;
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
+ Status = STATUS_FAILURE ;
+ break;
+ }
+ break;
+ case VSA0 :
+ case VSA1 :
+ case VSA2 :
+ //Has to be decided
+ break ;
+ default :
+ Status = STATUS_FAILURE ;
+ break;
+
+ }
+
+ Adapter->bHeaderChangeAllowed = FALSE ;
+ return Status;
+
+}
+
+/**
+BcmCopyISO - Used only for copying the ISO section
+@Adapater :- Bcm Driver Private Data Structure
+@sCopySectStrut :- Section copy structure
+
+Return value:- SUCCESS if copies successfully else negative error code
+
+**/
+INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
+{
+
+ PCHAR Buff = NULL;
+ FLASH2X_SECTION_VAL eISOReadPart = 0,eISOWritePart = 0;
+ UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
+ UINT uiTotalDataToCopy = 0;
+ BOOLEAN IsThisHeaderSector = FALSE ;
+ UINT sigOffset = 0;
+ UINT ISOLength = 0;
+ UINT Status = STATUS_SUCCESS;
+ UINT SigBuff[MAX_RW_SIZE];
+ UINT i = 0;
+
+ if(ReadISOSignature(Adapter,sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
+ return STATUS_FAILURE;
+ }
+
+ Status = BcmFlash2xBulkRead(Adapter,
+ &ISOLength,
+ sCopySectStrut.SrcSection,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageSize),
+ 4);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
+ return Status;
+ }
+
+ ISOLength = htonl(ISOLength);
+
+ if(ISOLength % Adapter->uiSectorSize)
+ {
+ ISOLength = Adapter->uiSectorSize*(1 + ISOLength/Adapter->uiSectorSize);
+ }
+
+ sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);
+
+ Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
+
+ if(Buff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for section size");
+ return -ENOMEM;
+ }
+
+ if(sCopySectStrut.SrcSection ==ISO_IMAGE1 && sCopySectStrut.DstSection ==ISO_IMAGE2)
+ {
+ eISOReadPart = ISO_IMAGE1 ;
+ eISOWritePart = ISO_IMAGE2 ;
+ uiReadOffsetWithinPart = 0;
+ uiWriteOffsetWithinPart = 0 ;
+
+ uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
+
+ if(uiTotalDataToCopy < ISOLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
+ return STATUS_FAILURE;
+ }
+
+ uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
+
+ if(uiTotalDataToCopy < ISOLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
+ return STATUS_FAILURE;
+ }
+
+ uiTotalDataToCopy = ISOLength;
+
+ CorruptISOSig(Adapter,ISO_IMAGE2);
+
+ while(uiTotalDataToCopy)
+ {
+ if(uiTotalDataToCopy == Adapter->uiSectorSize)
+ {
+ //Setting for write of first sector. First sector is assumed to be written in last
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
+ eISOReadPart = ISO_IMAGE1 ;
+ uiReadOffsetWithinPart = 0;
+ eISOWritePart = ISO_IMAGE2;
+ uiWriteOffsetWithinPart = 0 ;
+ IsThisHeaderSector = TRUE ;
+
+ }
+ else
+ {
+ uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
+ uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
+
+ if((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) ))
+ {
+ eISOReadPart = ISO_IMAGE1_PART2 ;
+ uiReadOffsetWithinPart = 0;
+ }
+ if((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
+ {
+ eISOReadPart = ISO_IMAGE1_PART3 ;
+ uiReadOffsetWithinPart = 0;
+ }
+ if((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)))
+ {
+ eISOWritePart = ISO_IMAGE2_PART2 ;
+ uiWriteOffsetWithinPart = 0;
+ }
+ if((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
+ {
+ eISOWritePart = ISO_IMAGE2_PART3 ;
+ uiWriteOffsetWithinPart = 0;
+ }
+ }
+
+ Status = BcmFlash2xBulkRead(Adapter,
+ (PUINT)Buff,
+ eISOReadPart,
+ uiReadOffsetWithinPart,
+ Adapter->uiSectorSize
+ );
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
+ break;
+ }
+
+ if(IsThisHeaderSector == TRUE)
+ {
+ //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
+ memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
+
+ for(i = 0; i < MAX_RW_SIZE;i++)
+ *(Buff + sigOffset + i) = 0xFF;
+ }
+ Adapter->bHeaderChangeAllowed = TRUE ;
+
+ Status = BcmFlash2xBulkWrite(Adapter,
+ (PUINT)Buff,
+ eISOWritePart,
+ uiWriteOffsetWithinPart,
+ Adapter->uiSectorSize,
+ TRUE);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
+ break;
+ }
+
+ Adapter->bHeaderChangeAllowed = FALSE;
+
+ if(IsThisHeaderSector == TRUE)
+ {
+ WriteToFlashWithoutSectorErase(Adapter,
+ SigBuff,
+ eISOWritePart,
+ sigOffset,
+ MAX_RW_SIZE);
+ IsThisHeaderSector = FALSE ;
+ }
+ //substracting the written Data
+ uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
+ }
+
+
+ }
+
+ if(sCopySectStrut.SrcSection ==ISO_IMAGE2 && sCopySectStrut.DstSection ==ISO_IMAGE1)
+ {
+ eISOReadPart = ISO_IMAGE2 ;
+ eISOWritePart = ISO_IMAGE1 ;
+ uiReadOffsetWithinPart = 0;
+ uiWriteOffsetWithinPart = 0 ;
+
+ uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
+
+ if(uiTotalDataToCopy < ISOLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature");
+ return STATUS_FAILURE;
+ }
+
+ uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)+
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
+ (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
+
+ if(uiTotalDataToCopy < ISOLength)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size");
+ return STATUS_FAILURE;
+ }
+
+ uiTotalDataToCopy = ISOLength;
+
+ CorruptISOSig(Adapter,ISO_IMAGE1);
+
+ while(uiTotalDataToCopy)
+ {
+ if(uiTotalDataToCopy == Adapter->uiSectorSize)
+ {
+ //Setting for write of first sector. First sector is assumed to be written in last
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Writing the signature sector");
+ eISOReadPart = ISO_IMAGE2 ;
+ uiReadOffsetWithinPart = 0;
+ eISOWritePart = ISO_IMAGE1;
+ uiWriteOffsetWithinPart = 0 ;
+ IsThisHeaderSector = TRUE;
+
+ }
+ else
+ {
+ uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize ;
+ uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize ;
+
+ if((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) ))
+ {
+ eISOReadPart = ISO_IMAGE2_PART2 ;
+ uiReadOffsetWithinPart = 0;
+ }
+ if((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start)))
+ {
+ eISOReadPart = ISO_IMAGE2_PART3 ;
+ uiReadOffsetWithinPart = 0;
+ }
+ if((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start)))
+ {
+ eISOWritePart = ISO_IMAGE1_PART2 ;
+ uiWriteOffsetWithinPart = 0;
+ }
+ if((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start)))
+ {
+ eISOWritePart = ISO_IMAGE1_PART3 ;
+ uiWriteOffsetWithinPart = 0;
+ }
+ }
+
+ Status = BcmFlash2xBulkRead(Adapter,
+ (PUINT)Buff,
+ eISOReadPart,
+ uiReadOffsetWithinPart,
+ Adapter->uiSectorSize
+ );
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
+ break;
+ }
+
+ if(IsThisHeaderSector == TRUE)
+ {
+ //If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
+ memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
+
+ for(i = 0; i < MAX_RW_SIZE;i++)
+ *(Buff + sigOffset + i) = 0xFF;
+
+ }
+ Adapter->bHeaderChangeAllowed = TRUE ;
+ Status = BcmFlash2xBulkWrite(Adapter,
+ (PUINT)Buff,
+ eISOWritePart,
+ uiWriteOffsetWithinPart,
+ Adapter->uiSectorSize,
+ TRUE);
+
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
+ break;
+ }
+
+ Adapter->bHeaderChangeAllowed = FALSE ;
+
+ if(IsThisHeaderSector == TRUE)
+ {
+ WriteToFlashWithoutSectorErase(Adapter,
+ SigBuff,
+ eISOWritePart,
+ sigOffset,
+ MAX_RW_SIZE);
+ IsThisHeaderSector = FALSE ;
+ }
+
+ //substracting the written Data
+ uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize ;
+ }
+
+
+ }
+
+ bcm_kfree(Buff);
+
+ return Status;
+}
+/**
+BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
+ It will corrupt the sig, if Section is writable, by making first bytes as zero.
+@Adapater :- Bcm Driver Private Data Structure
+@eFlash2xSectionVal :- Flash section val which has header
+
+Return Value :-
+ Sucess :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
+ Failure :-Return negative error code
+
+
+**/
+INT BcmFlash2xCorruptSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+{
+
+ INT Status = STATUS_SUCCESS ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Section Value :%x \n", eFlash2xSectionVal);
+
+ if((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2))
+ {
+ Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
+ }
+ else if(eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2)
+ {
+ Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Given Section <%d>does not have Header",eFlash2xSectionVal);
+ return STATUS_SUCCESS;
+ }
+ return Status;
+}
+/**
+BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
+ header and Write Permission.
+@Adapater :- Bcm Driver Private Data Structure
+@eFlashSectionVal :- Flash section val which has header
+
+Return Value :-
+ Sucess :- If Section is present and writable write the sig and return STATUS_SUCCESS
+ Failure :-Return negative error code
+
+**/
+INT BcmFlash2xWriteSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
+{
+
+ UINT uiSignature = 0 ;
+ UINT uiOffset = 0;
+ //DSD_HEADER dsdHeader = {0};
+
+ if(Adapter->bSigCorrupted == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Signature is not corrupted by driver, hence not restoring\n");
+ return STATUS_SUCCESS;
+ }
+ if(Adapter->bAllDSDWriteAllow == FALSE)
+ {
+ if(IsSectionWritable(Adapter,eFlashSectionVal) == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence can't Write signature");
+ return SECTOR_IS_NOT_WRITABLE;
+ }
+ }
+ if((eFlashSectionVal == DSD0) ||(eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2))
+ {
+ uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER) ;
+ uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader ;
+
+ uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber);
+
+ if((ReadDSDSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corrupted Pattern is not there. Hence won't write sig");
+ return STATUS_FAILURE;
+ }
+
+ }
+ else if((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2))
+ {
+ uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
+ //uiOffset = 0;
+ uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber);
+ if((ReadISOSignature(Adapter,eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Currupted Pattern is not there. Hence won't write sig");
+ return STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
+ return STATUS_FAILURE;
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Restoring the signature");
+
+
+ Adapter->bHeaderChangeAllowed = TRUE;
+ Adapter->bSigCorrupted = FALSE;
+ BcmFlash2xBulkWrite(Adapter, &uiSignature,eFlashSectionVal,uiOffset,SIGNATURE_SIZE,TRUE);
+ Adapter->bHeaderChangeAllowed = FALSE;
+
+
+
+ return STATUS_SUCCESS;
+}
+/**
+validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
+ if requested Bytes goes beyond the Requested section, it reports error.
+@Adapater :- Bcm Driver Private Data Structure
+@psFlash2xReadWrite :-Flash2x Read/write structure pointer
+
+Return values:-Return TRUE is request is valid else FALSE.
+
+
+**/
+INT validateFlash2xReadWrite(PMINI_ADAPTER Adapter, PFLASH2X_READWRITE psFlash2xReadWrite)
+{
+ UINT uiNumOfBytes = 0 ;
+ UINT uiSectStartOffset = 0 ;
+ UINT uiSectEndOffset = 0;
+ uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
+
+ if(IsSectionExistInFlash(Adapter,psFlash2xReadWrite->Section) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%x> does not exixt in Flash",psFlash2xReadWrite->Section);
+ return FALSE;
+ }
+ uiSectStartOffset = BcmGetSectionValStartOffset(Adapter,psFlash2xReadWrite->Section);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n",uiSectStartOffset,psFlash2xReadWrite->Section);
+ if((psFlash2xReadWrite->Section == ISO_IMAGE1) ||(psFlash2xReadWrite->Section == ISO_IMAGE2))
+ {
+ if(psFlash2xReadWrite->Section == ISO_IMAGE1)
+ {
+ uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1)+
+ BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART2) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART2)+
+ BcmGetSectionValEndOffset(Adapter,ISO_IMAGE1_PART3) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1_PART3);
+ }
+ else if(psFlash2xReadWrite->Section == ISO_IMAGE2)
+ {
+ uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2)+
+ BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART2) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART2)+
+ BcmGetSectionValEndOffset(Adapter,ISO_IMAGE2_PART3) -
+ BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2_PART3);
+
+ }
+
+ //since this uiSectEndoffset is the size of iso Image. hence for calculating the vitual endoffset
+ //it should be added in startoffset. so that check done in last of this function can be valued.
+ uiSectEndOffset = uiSectStartOffset + uiSectEndOffset ;
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Total size of the ISO Image :%x",uiSectEndOffset);
+ }
+ else
+ uiSectEndOffset = BcmGetSectionValEndOffset(Adapter,psFlash2xReadWrite->Section);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x \n",uiSectEndOffset);
+
+ //Checking the boundary condition
+ if((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
+ return TRUE;
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid Request....");
+ return FALSE;
+ }
+
+}
+
+/**
+IsFlash2x :- check for Flash 2.x
+@Adapater :- Bcm Driver Private Data Structure
+
+Return value:-
+ return TRUE if flah2.x of hgher version else return false.
+**/
+
+INT IsFlash2x(PMINI_ADAPTER Adapter)
+{
+ if(Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
+ return TRUE ;
+ else
+ return FALSE;
+}
+/**
+GetFlashBaseAddr :- Calculate the Flash Base address
+@Adapater :- Bcm Driver Private Data Structure
+
+Return Value:-
+ Success :- Base Address of the Flash
+**/
+
+INT GetFlashBaseAddr(PMINI_ADAPTER Adapter)
+{
+
+ UINT uiBaseAddr = 0;
+
+ if(Adapter->bDDRInitDone)
+ {
+ /*
+ For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
+ In case of Raw Read... use the default value
+ */
+ if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
+ !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
+ )
+ uiBaseAddr = Adapter->uiFlashBaseAdd ;
+ else
+ uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
+ }
+ else
+ {
+ /*
+ For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
+ In case of Raw Read... use the default value
+ */
+ if(Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
+ !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))
+ )
+ uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
+ else
+ uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
+ }
+
+ return uiBaseAddr ;
+}
+/**
+BcmCopySection :- This API is used to copy the One section in another. Both section should
+ be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
+
+@Adapater :- Bcm Driver Private Data Structure
+@SrcSection :- Source section From where data has to be copied
+@DstSection :- Destination section to which data has to be copied
+@offset :- Offset from/to where data has to be copied from one section to another.
+@numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
+ in case of numofBytes equal zero complete section will be copied.
+
+Return Values-
+ Sucess : Return STATUS_SUCCESS
+ Faillure :- return negative error code
+
+**/
+
+INT BcmCopySection(PMINI_ADAPTER Adapter,
+ FLASH2X_SECTION_VAL SrcSection,
+ FLASH2X_SECTION_VAL DstSection,
+ UINT offset,
+ UINT numOfBytes)
+{
+ UINT BuffSize = 0 ;
+ UINT BytesToBeCopied = 0;
+ PUCHAR pBuff = NULL ;
+ INT Status = STATUS_SUCCESS ;
+ if(SrcSection == DstSection)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source and Destination should be different ...try again");
+ return -EINVAL;
+ }
+ if((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source should be DSD subsection");
+ return -EINVAL;
+ }
+ if((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destination should be DSD subsection");
+ return -EINVAL;
+ }
+
+ #if 0
+ else
+ {
+ if((SrcSection == VSA0) || (SrcSection == VSA1) || (SrcSection == VSA2))
+ {
+ if((DstSection != VSA0) && (DstSection != VSA1) && (DstSection != VSA2))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Source and Destion secton is not of same type");
+ return -EINVAL;
+ }
+ }
+
+ }
+ #endif
+ //if offset zero means have to copy complete secton
+
+ if(numOfBytes == 0)
+ {
+ numOfBytes = BcmGetSectionValEndOffset(Adapter,SrcSection)
+ - BcmGetSectionValStartOffset(Adapter,SrcSection);
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL," Section Size :0x%x",numOfBytes);
+ }
+
+ if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,SrcSection)
+ - BcmGetSectionValStartOffset(Adapter,SrcSection))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
+ offset, numOfBytes);
+ return -EINVAL;
+ }
+
+ if((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter,DstSection)
+ - BcmGetSectionValStartOffset(Adapter,DstSection))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
+ offset, numOfBytes);
+ return -EINVAL;
+ }
+
+
+ if(numOfBytes > Adapter->uiSectorSize )
+ BuffSize = Adapter->uiSectorSize;
+ else
+ BuffSize = numOfBytes ;
+
+ pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL);
+ if(pBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed.. ");
+ return -ENOMEM;
+ }
+
+
+ BytesToBeCopied = Adapter->uiSectorSize ;
+ if(offset % Adapter->uiSectorSize)
+ BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
+ if(BytesToBeCopied > numOfBytes)
+ BytesToBeCopied = numOfBytes ;
+
+
+
+ Adapter->bHeaderChangeAllowed = TRUE;
+
+ do
+ {
+ Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset,BytesToBeCopied);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection,BytesToBeCopied);
+ break;
+ }
+ Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pBuff,DstSection,offset,BytesToBeCopied,FALSE);
+ if(Status)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection,BytesToBeCopied);
+ break;
+ }
+ offset = offset + BytesToBeCopied;
+ numOfBytes = numOfBytes - BytesToBeCopied ;
+ if(numOfBytes)
+ {
+ if(numOfBytes > Adapter->uiSectorSize )
+ BytesToBeCopied = Adapter->uiSectorSize;
+ else
+ BytesToBeCopied = numOfBytes;
+ }
+ }while(numOfBytes > 0) ;
+ bcm_kfree(pBuff);
+ Adapter->bHeaderChangeAllowed = FALSE ;
+ return Status;
+}
+
+/**
+SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
+@Adapater :- Bcm Driver Private Data Structure
+@pBuff :- Data buffer that has to be written in sector having the header map.
+@uiOffset :- Flash offset that has to be written.
+
+Return value :-
+ Sucess :- On sucess return STATUS_SUCCESS
+ Faillure :- Return negative error code
+
+**/
+
+INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset)
+{
+ UINT offsetToProtect = 0,HeaderSizeToProtect =0;
+ BOOLEAN bHasHeader = FALSE ;
+ PUCHAR pTempBuff =NULL;
+ UINT uiSectAlignAddr = 0;
+ UINT sig = 0;
+
+ #if 0
+ //if Chenges in Header is allowed, Return back
+ if(Adapter->bHeaderChangeAllowed == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Header Change is allowed");
+ return STATUS_SUCCESS ;
+ }
+ #endif
+ //making the offset sector alligned
+ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
+
+
+ if((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD2)- Adapter->uiSectorSize)||
+ (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD1)- Adapter->uiSectorSize)||
+ (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter,DSD0)- Adapter->uiSectorSize))
+ {
+
+ //offset from the sector boundry having the header map
+ offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
+ HeaderSizeToProtect = sizeof(DSD_HEADER);
+ bHasHeader = TRUE ;
+ }
+
+ if(uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE1) ||
+ uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter,ISO_IMAGE2))
+ {
+ offsetToProtect = 0;
+ HeaderSizeToProtect = sizeof(ISO_HEADER);
+ bHasHeader = TRUE;
+ }
+ //If Header is present overwrite passed buffer with this
+ if(bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE))
+ {
+ pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL);
+ if(pTempBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed ");
+ return -ENOMEM;
+ }
+ //Read header
+ BeceemFlashBulkRead(Adapter,(PUINT)pTempBuff,(uiSectAlignAddr + offsetToProtect),HeaderSizeToProtect);
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pTempBuff ,HeaderSizeToProtect);
+ //Replace Buffer content with Header
+ memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect);
+
+ bcm_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 ;
+}
+INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset)
+{
+ UINT GPIOConfig = 0 ;
+
+
+ if(Adapter->bFlashRawRead == FALSE)
+ {
+ //Applicable for Flash2.x
+ if(IsFlash2x(Adapter) == FALSE)
+ return STATUS_SUCCESS;
+ }
+
+ if(offset/FLASH_PART_SIZE)
+ {
+ //bit[14..12] -> will select make Active CS1, CS2 or CS3
+ // Select CS1, CS2 and CS3 (CS0 is dedicated pin)
+ rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
+ GPIOConfig |= (7 << 12);
+ wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
+ }
+
+ return STATUS_SUCCESS ;
+}
+/**
+BcmDoChipSelect : This will selcet the appropriate chip for writing.
+@Adapater :- Bcm Driver Private Data Structure
+
+OutPut:-
+ Select the Appropriate chip and retrn status Sucess
+**/
+INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset)
+{
+ UINT FlashConfig = 0;
+ INT ChipNum = 0;
+ UINT GPIOConfig = 0;
+ UINT PartNum = 0;
+
+ ChipNum = offset / FLASH_PART_SIZE ;
+
+ //
+ // Chip Select mapping to enable flash0.
+ // To select flash 0, we have to OR with (0<<12).
+ // ORing 0 will have no impact so not doing that part.
+ // In future if Chip select value changes from 0 to non zero,
+ // That needs be taken care with backward comaptibility. No worries for now.
+ //
+
+ /*
+ SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
+ if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
+ Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
+ power down modes (Idle mode/shutdown mode), the values in the register will be different.
+ */
+
+ if(Adapter->SelectedChip == ChipNum)
+ return STATUS_SUCCESS;
+
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum);
+ Adapter->SelectedChip = ChipNum ;
+
+ //bit[13..12] will select the appropriate chip
+ rdmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
+ rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
+
+ {
+ switch(ChipNum)
+ {
+ case 0:
+ PartNum = 0;
+ break;
+ case 1:
+ PartNum = 3;
+ GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
+ break;
+ case 2:
+ PartNum = 1;
+ GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
+ break;
+ case 3:
+ PartNum = 2;
+ GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
+ break;
+ }
+ }
+ /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
+ nothing to do... can return immediately.
+ ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
+ Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
+ These values are not written by host other than during CHIP_SELECT.
+ */
+ if(PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
+ return STATUS_SUCCESS;
+
+ //clearing the bit[13..12]
+ FlashConfig &= 0xFFFFCFFF;
+ FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); //00
+
+ wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
+ udelay(100);
+
+ wrmalt(Adapter,FLASH_CONFIG_REG, &FlashConfig, 4);
+ udelay(100);
+
+ return STATUS_SUCCESS;
+
+}
+INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
+{
+ UINT uiDSDsig = 0;
+ //UINT sigoffsetInMap = 0;
+ //DSD_HEADER dsdHeader = {0};
+
+
+ //sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader;
+
+ if(dsd != DSD0 && dsd != DSD1 && dsd != DSD2)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for DSDs");
+ return STATUS_FAILURE;
+ }
+ BcmFlash2xBulkRead(Adapter,
+ &uiDSDsig,
+ dsd,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER,DSDImageMagicNumber),
+ SIGNATURE_SIZE);
+
+ uiDSDsig = ntohl(uiDSDsig);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD SIG :%x", uiDSDsig);
+
+ return uiDSDsig ;
+}
+INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd)
+{
+ //UINT priOffsetInMap = 0 ;
+ unsigned int uiDSDPri = STATUS_FAILURE;
+ //DSD_HEADER dsdHeader = {0};
+ //priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
+ if(IsSectionWritable(Adapter,dsd))
+ {
+ if(ReadDSDSignature(Adapter,dsd)== DSD_IMAGE_MAGIC_NUMBER)
+ {
+ BcmFlash2xBulkRead(Adapter,
+ &uiDSDPri,
+ dsd,
+ Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader +FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
+ 4);
+
+ uiDSDPri = ntohl(uiDSDPri);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"DSD<%x> Priority :%x", dsd, uiDSDPri);
+
+ }
+ }
+ return uiDSDPri;
+}
+FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter)
+{
+ INT DSDHighestPri = STATUS_FAILURE;
+ INT DsdPri= 0 ;
+ FLASH2X_SECTION_VAL HighestPriDSD = 0 ;
+
+ if(IsSectionWritable(Adapter,DSD2))
+ {
+ DSDHighestPri = ReadDSDPriority(Adapter,DSD2);
+ HighestPriDSD = DSD2 ;
+ }
+ if(IsSectionWritable(Adapter,DSD1))
+ {
+ DsdPri = ReadDSDPriority(Adapter,DSD1);
+ if(DSDHighestPri < DsdPri)
+ {
+ DSDHighestPri = DsdPri ;
+ HighestPriDSD = DSD1;
+ }
+ }
+ if(IsSectionWritable(Adapter,DSD0))
+ {
+ DsdPri = ReadDSDPriority(Adapter,DSD0);
+ if(DSDHighestPri < DsdPri)
+ {
+ DSDHighestPri = DsdPri ;
+ HighestPriDSD = DSD0;
+ }
+ }
+ if(HighestPriDSD)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri);
+ return HighestPriDSD ;
+}
+
+INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
+{
+ UINT uiISOsig = 0;
+ //UINT sigoffsetInMap = 0;
+ //ISO_HEADER ISOHeader = {0};
+
+
+ //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
+
+ if(iso != ISO_IMAGE1 && iso != ISO_IMAGE2)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"passed section value is not for ISOs");
+ return STATUS_FAILURE;
+ }
+ BcmFlash2xBulkRead(Adapter,
+ &uiISOsig,
+ iso,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER,ISOImageMagicNumber),
+ SIGNATURE_SIZE);
+
+ uiISOsig = ntohl(uiISOsig);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO SIG :%x", uiISOsig);
+
+ return uiISOsig ;
+}
+INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso)
+{
+
+ unsigned int ISOPri = STATUS_FAILURE;
+ if(IsSectionWritable(Adapter,iso))
+ {
+ if(ReadISOSignature(Adapter,iso)== ISO_IMAGE_MAGIC_NUMBER)
+ {
+ BcmFlash2xBulkRead(Adapter,
+ &ISOPri,
+ iso,
+ 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
+ 4);
+
+ ISOPri = ntohl(ISOPri);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"ISO<%x> Priority :%x", iso, ISOPri);
+
+ }
+ }
+ return ISOPri;
+}
+FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter)
+{
+ INT ISOHighestPri = STATUS_FAILURE;
+ INT ISOPri= 0 ;
+ FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL ;
+
+ if(IsSectionWritable(Adapter,ISO_IMAGE2))
+ {
+ ISOHighestPri = ReadISOPriority(Adapter,ISO_IMAGE2);
+ HighestPriISO = ISO_IMAGE2 ;
+ }
+ if(IsSectionWritable(Adapter,ISO_IMAGE1))
+ {
+ ISOPri = ReadISOPriority(Adapter,ISO_IMAGE1);
+ if(ISOHighestPri < ISOPri)
+ {
+ ISOHighestPri = ISOPri ;
+ HighestPriISO = ISO_IMAGE1;
+ }
+ }
+ if(HighestPriISO)
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Highest ISO :%x and its Pri :%x",HighestPriISO,ISOHighestPri);
+ return HighestPriISO ;
+}
+INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter,
+ PUINT pBuff,
+ FLASH2X_SECTION_VAL eFlash2xSectionVal,
+ UINT uiOffset,
+ UINT uiNumBytes
+ )
+{
+#if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
+ UINT uiTemp = 0, value = 0 ;
+ UINT i = 0;
+ UINT uiPartOffset = 0;
+#endif
+ UINT uiStartOffset = 0;
+ //Adding section start address
+ INT Status = STATUS_SUCCESS;
+ PUCHAR pcBuff = (PUCHAR)pBuff;
+
+ if(uiNumBytes % Adapter->ulFlashWriteSize)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
+ return STATUS_FAILURE;
+ }
+
+ uiStartOffset = BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
+
+ if(IsSectionExistInVendorInfo(Adapter,eFlash2xSectionVal))
+ {
+ return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
+ }
+
+ uiOffset = uiOffset + uiStartOffset;
+
+#if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
+ Status = bcmflash_raw_writenoerase((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE), pcBuff,uiNumBytes);
+#else
+ rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ value = 0;
+ wrmalt(Adapter, 0x0f000C80,&value, sizeof(value));
+
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+ BcmDoChipSelect(Adapter,uiOffset);
+ uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
+
+ for(i = 0 ; i< uiNumBytes; i += Adapter->ulFlashWriteSize)
+ {
+ if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
+ Status = flashByteWrite(Adapter,uiPartOffset, pcBuff);
+ else
+ Status = flashWrite(Adapter,uiPartOffset, pcBuff);
+
+ if(Status != STATUS_SUCCESS)
+ break;
+
+ pcBuff = pcBuff + Adapter->ulFlashWriteSize;
+ uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize;
+ }
+ wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
+ Adapter->SelectedChip = RESET_CHIP_SELECT;
+#endif
+
+ return Status;
+}
+
+#if 0
+UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType)
+{
+
+ UINT numOfWRSubSec = 0;
+ switch(secType)
+ {
+ case ISO :
+ if(IsSectionWritable(Adapter,ISO_IMAGE1))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ if(IsSectionWritable(Adapter,ISO_IMAGE2))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ break;
+
+ case DSD :
+ if(IsSectionWritable(Adapter,DSD2))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ if(IsSectionWritable(Adapter,DSD1))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ if(IsSectionWritable(Adapter,DSD0))
+ numOfWRSubSec = numOfWRSubSec + 1;
+ break ;
+
+ case VSA :
+ //for VSA Add code Here
+ default :
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Invalid secton<%d> is passed", secType);\
+ numOfWRSubSec = 0;
+
+ }
+ return numOfWRSubSec;
+}
+#endif
+BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section)
+{
+
+ BOOLEAN SectionPresent = FALSE ;
+
+ switch(section)
+ {
+
+ case ISO_IMAGE1 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectionPresent = TRUE ;
+ break;
+ case ISO_IMAGE2 :
+ if((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
+ (IsNonCDLessDevice(Adapter) == FALSE))
+ SectionPresent = TRUE ;
+ break;
+ case DSD0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case DSD1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case DSD2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case VSA0 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case VSA1 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case VSA2 :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case SCSI :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ case CONTROL_SECTION :
+ if(Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
+ SectionPresent = TRUE ;
+ break;
+ default :
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section Does not exist in Flash 2.x");
+ SectionPresent = FALSE;
+ }
+ return SectionPresent ;
+}
+INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section)
+{
+ INT offset = STATUS_FAILURE;
+ INT Status = FALSE;
+ if(IsSectionExistInFlash(Adapter,Section) == FALSE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section <%d> does not exixt", Section);
+ return FALSE;
+ }
+ offset = BcmGetSectionValStartOffset(Adapter,Section);
+ if(offset == INVALID_OFFSET)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section<%d> does not exixt", Section);
+ return FALSE;
+ }
+
+ if(IsSectionExistInVendorInfo(Adapter,Section))
+ {
+ return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
+ }
+
+ Status = IsOffsetWritable(Adapter,offset);
+ return Status ;
+}
+
+INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+{
+
+ PUCHAR pBuff = NULL;
+ UINT sig = 0;
+ UINT uiOffset = 0;
+ UINT BlockStatus = 0;
+ UINT uiSectAlignAddr = 0;
+
+ Adapter->bSigCorrupted = FALSE;
+
+ if(Adapter->bAllDSDWriteAllow == FALSE)
+ {
+ if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
+ return SECTOR_IS_NOT_WRITABLE;
+ }
+ }
+
+ pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
+ if(pBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
+ return -ENOMEM ;
+ }
+
+ uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER);
+ uiOffset -= MAX_RW_SIZE ;
+
+ BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset,MAX_RW_SIZE);
+
+
+ sig = *((PUINT)(pBuff +12));
+ sig =ntohl(sig);
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE);
+ //Now corrupting the sig by corrupting 4th last Byte.
+ *(pBuff + 12) = 0;
+
+ if(sig == DSD_IMAGE_MAGIC_NUMBER)
+ {
+ Adapter->bSigCorrupted = TRUE;
+ if(Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
+ {
+ uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize -1);
+ BlockStatus = BcmFlashUnProtectBlock(Adapter,uiSectAlignAddr,Adapter->uiSectorSize);
+
+ WriteToFlashWithoutSectorErase(Adapter,(PUINT)(pBuff + 12),eFlash2xSectionVal,
+ (uiOffset + 12),BYTE_WRITE_SUPPORT);
+ if(BlockStatus)
+ {
+ BcmRestoreBlockProtectStatus(Adapter,BlockStatus);
+ BlockStatus = 0;
+ }
+ }
+ else
+ {
+ WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
+ uiOffset ,MAX_RW_SIZE);
+ }
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
+ bcm_kfree(pBuff);
+ return STATUS_FAILURE;
+ }
+
+ bcm_kfree(pBuff);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature");
+ return STATUS_SUCCESS ;
+}
+
+INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
+{
+
+ PUCHAR pBuff = NULL;
+ UINT sig = 0;
+ UINT uiOffset = 0;
+
+ Adapter->bSigCorrupted = FALSE;
+
+ if(IsSectionWritable(Adapter,eFlash2xSectionVal) != TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Section is not Writable...Hence cant Corrupt signature");
+ return SECTOR_IS_NOT_WRITABLE;
+ }
+
+ pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
+ if(pBuff == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allocate memorey");
+ return -ENOMEM ;
+ }
+
+ uiOffset = 0;
+
+ BcmFlash2xBulkRead(Adapter, (PUINT)pBuff,eFlash2xSectionVal,uiOffset, MAX_RW_SIZE);
+
+ sig = *((PUINT)pBuff);
+ sig =ntohl(sig);
+
+ //corrupt signature
+ *pBuff = 0;
+
+ if(sig == ISO_IMAGE_MAGIC_NUMBER)
+ {
+ Adapter->bSigCorrupted = TRUE;
+ WriteToFlashWithoutSectorErase(Adapter,(PUINT)pBuff,eFlash2xSectionVal,
+ uiOffset ,Adapter->ulFlashWriteSize);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header");
+ bcm_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);
+
+ bcm_kfree(pBuff);
+ return STATUS_SUCCESS ;
+}
+
+BOOLEAN IsNonCDLessDevice(PMINI_ADAPTER Adapter)
+{
+ if(Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
+ return TRUE;
+ else
+ return FALSE ;
+}
+
OpenPOWER on IntegriCloud