diff options
Diffstat (limited to 'drivers/staging/bcm/nvm.c')
-rw-r--r-- | drivers/staging/bcm/nvm.c | 146 |
1 files changed, 97 insertions, 49 deletions
diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 63be3be62ebd..ce09473fbb1f 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -2,35 +2,52 @@ #define DWORD unsigned int -static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset); +static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, + unsigned int offset); static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter); static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter); static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter); static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter); -static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize); +static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, + unsigned int FlashSectorSizeSig, + unsigned int FlashSectorSize); static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter); static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter); static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter); static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter); -static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal); - -static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset); -static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section); -static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section); - -static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd); -static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd); -static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso); -static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso); - -static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal); -static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal); -static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiSectAlignAddr); -static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, - enum bcm_flash2x_section_val eFlash2xSectionVal, - unsigned int uiOffset, unsigned int uiNumBytes); +static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, + enum bcm_flash2x_section_val eFlash2xSectionVal); + +static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, + unsigned int uiOffset); +static int IsSectionWritable(struct bcm_mini_adapter *Adapter, + enum bcm_flash2x_section_val Section); +static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, + enum bcm_flash2x_section_val section); + +static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, + enum bcm_flash2x_section_val dsd); +static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, + enum bcm_flash2x_section_val dsd); +static int ReadISOPriority(struct bcm_mini_adapter *Adapter, + enum bcm_flash2x_section_val iso); +static int ReadISOSignature(struct bcm_mini_adapter *Adapter, + enum bcm_flash2x_section_val iso); + +static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, + enum bcm_flash2x_section_val eFlash2xSectionVal); +static int CorruptISOSig(struct bcm_mini_adapter *Adapter, + enum bcm_flash2x_section_val eFlash2xSectionVal); +static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, + PUCHAR pBuff, + unsigned int uiSectAlignAddr); +static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, + PUINT pBuff, + enum bcm_flash2x_section_val eFlash2xSectionVal, + unsigned int uiOffset, + unsigned int uiNumBytes); static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter); static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter); @@ -361,6 +378,7 @@ int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, } else { /* Handle the reads less than 4 bytes... */ PUCHAR pCharBuff = (PUCHAR)pBuffer; + pCharBuff += uiIndex; if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) { memcpy(pCharBuff, &uiData[0], uiBytesRemaining); /* copy only bytes requested. */ @@ -914,6 +932,7 @@ static int flashWriteStatus(struct bcm_mini_adapter *Adapter, static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus) { unsigned int value; + value = (FLASH_CMD_WRITE_ENABLE << 24); wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); @@ -1014,6 +1033,45 @@ static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned i return ulStatus; } +static int bulk_read_complete_sector(struct bcm_mini_adapter *ad, + UCHAR read_bk[], + PCHAR tmpbuff, + unsigned int offset, + unsigned int partoff) +{ + unsigned int i; + int j; + int bulk_read_stat; + FP_FLASH_WRITE_STATUS writef = + ad->fpFlashWriteWithStatusCheck; + + for (i = 0; i < ad->uiSectorSize; i += MAX_RW_SIZE) { + bulk_read_stat = BeceemFlashBulkRead(ad, + (PUINT)read_bk, + offset + i, + MAX_RW_SIZE); + + if (bulk_read_stat != STATUS_SUCCESS) + continue; + + if (ad->ulFlashWriteSize == 1) { + for (j = 0; j < 16; j++) { + if ((read_bk[j] != tmpbuff[i + j]) && + (STATUS_SUCCESS != (*writef)(ad, partoff + i + j, &tmpbuff[i + j]))) { + return STATUS_FAILURE; + } + } + } else { + if ((memcmp(read_bk, &tmpbuff[i], MAX_RW_SIZE)) && + (STATUS_SUCCESS != (*writef)(ad, partoff + i, &tmpbuff[i]))) { + return STATUS_FAILURE; + } + } + } + + return STATUS_SUCCESS; +} + /* * Procedure: BeceemFlashBulkWrite * @@ -1150,28 +1208,16 @@ static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, /* do_gettimeofday(&tw); * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Total time taken in Write to Flash :%ld ms\n", (tw.tv_sec *1000 + tw.tv_usec/1000) - (te.tv_sec *1000 + te.tv_usec/1000)); */ - for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) { - if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) { - if (Adapter->ulFlashWriteSize == 1) { - unsigned int uiReadIndex = 0; - for (uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++) { - if (ucReadBk[uiReadIndex] != pTempBuff[uiIndex + uiReadIndex]) { - if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex + uiReadIndex, &pTempBuff[uiIndex+uiReadIndex])) { - Status = STATUS_FAILURE; - goto BeceemFlashBulkWrite_EXIT; - } - } - } - } else { - if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) { - if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex, &pTempBuff[uiIndex])) { - Status = STATUS_FAILURE; - goto BeceemFlashBulkWrite_EXIT; - } - } - } - } + + if (STATUS_FAILURE == bulk_read_complete_sector(Adapter, + ucReadBk, + pTempBuff, + uiOffsetFromSectStart, + uiPartOffset)) { + 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)); */ @@ -1868,6 +1914,7 @@ int BeceemNVMWrite(struct bcm_mini_adapter *Adapter, 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); @@ -2455,6 +2502,7 @@ static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) #endif unsigned int uiFlashLayoutMajorVersion; + Adapter->uiFlashLayoutMinorVersion = 0; Adapter->uiFlashLayoutMajorVersion = 0; Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR; @@ -3321,7 +3369,7 @@ int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_secti SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1; - if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) { + 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 @@ -3381,7 +3429,7 @@ int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_secti } SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1; - if (SectImagePriority <= 0) { + 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 @@ -3487,11 +3535,10 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section return STATUS_FAILURE; } - Status = BcmFlash2xBulkRead(Adapter, - &ISOLength, - sCopySectStrut.SrcSection, - 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize), - 4); + Status = BcmFlash2xBulkRead(Adapter, &ISOLength, + sCopySectStrut.SrcSection, + 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize), + 4); if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n"); return Status; @@ -3591,7 +3638,7 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section 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); + memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff)); for (i = 0; i < MAX_RW_SIZE; i++) *(Buff + sigOffset + i) = 0xFF; @@ -3704,7 +3751,7 @@ int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section 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); + memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff)); for (i = 0; i < MAX_RW_SIZE; i++) *(Buff + sigOffset + i) = 0xFF; @@ -4319,6 +4366,7 @@ static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_s static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso) { unsigned int ISOPri = STATUS_FAILURE; + if (IsSectionWritable(Adapter, iso)) { if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) { BcmFlash2xBulkRead(Adapter, |