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