3 #define DWORD unsigned int
5 static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter,
7 static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter);
8 static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter);
9 static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter);
10 static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter);
11 static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter,
12 unsigned int FlashSectorSizeSig,
13 unsigned int FlashSectorSize);
15 static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter);
16 static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter);
17 static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter);
18 static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter);
20 static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter,
21 enum bcm_flash2x_section_val eFlash2xSectionVal);
23 static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter,
24 unsigned int uiOffset);
25 static int IsSectionWritable(struct bcm_mini_adapter *Adapter,
26 enum bcm_flash2x_section_val Section);
27 static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter,
28 enum bcm_flash2x_section_val section);
30 static int ReadDSDPriority(struct bcm_mini_adapter *Adapter,
31 enum bcm_flash2x_section_val dsd);
32 static int ReadDSDSignature(struct bcm_mini_adapter *Adapter,
33 enum bcm_flash2x_section_val dsd);
34 static int ReadISOPriority(struct bcm_mini_adapter *Adapter,
35 enum bcm_flash2x_section_val iso);
36 static int ReadISOSignature(struct bcm_mini_adapter *Adapter,
37 enum bcm_flash2x_section_val iso);
39 static int CorruptDSDSig(struct bcm_mini_adapter *Adapter,
40 enum bcm_flash2x_section_val eFlash2xSectionVal);
41 static int CorruptISOSig(struct bcm_mini_adapter *Adapter,
42 enum bcm_flash2x_section_val eFlash2xSectionVal);
43 static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter,
45 unsigned int uiSectAlignAddr);
46 static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
48 enum bcm_flash2x_section_val eFlash2xSectionVal,
49 unsigned int uiOffset,
50 unsigned int uiNumBytes);
51 static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter);
52 static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter);
54 static int BeceemFlashBulkRead(
55 struct bcm_mini_adapter *Adapter,
57 unsigned int uiOffset,
58 unsigned int uiNumBytes);
60 static int BeceemFlashBulkWrite(
61 struct bcm_mini_adapter *Adapter,
63 unsigned int uiOffset,
64 unsigned int uiNumBytes,
67 static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter);
69 static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, unsigned int dwAddress, unsigned int *pdwData, unsigned int dwNumData);
71 /* Procedure: ReadEEPROMStatusRegister
73 * Description: Reads the standard EEPROM Status Register.
76 * Adapter - ptr to Adapter object instance
80 static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter)
83 DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
84 unsigned int uiStatus = 0;
85 unsigned int value = 0;
86 unsigned int value1 = 0;
88 /* Read the EEPROM status register */
89 value = EEPROM_READ_STATUS_REGISTER;
90 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
92 while (dwRetries != 0) {
95 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
96 if (Adapter->device_removed == TRUE) {
97 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting....");
101 /* Wait for Avail bit to be set. */
102 if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) {
103 /* Clear the Avail/Full bits - which ever is set. */
104 value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
105 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
108 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
109 uiData = (UCHAR)value;
115 if (dwRetries == 0) {
116 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
117 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
118 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);
121 if (!(dwRetries%RETRIES_PER_DELAY))
126 } /* ReadEEPROMStatusRegister */
129 * Procedure: ReadBeceemEEPROMBulk
131 * Description: This routine reads 16Byte data from EEPROM
134 * Adapter - ptr to Adapter object instance
135 * dwAddress - EEPROM Offset to read the data from.
136 * pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY.
142 static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,
148 DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
149 unsigned int uiStatus = 0;
150 unsigned int value = 0;
151 unsigned int value1 = 0;
154 /* Flush the read and cmd queue. */
155 value = (EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH);
156 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
158 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
160 /* Clear the Avail/Full bits. */
161 value = (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
162 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
164 value = dwAddress | ((dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ);
165 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
167 while (dwRetries != 0) {
169 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
170 if (Adapter->device_removed == TRUE) {
171 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got Removed.hence exiting from loop...");
175 /* If we are reading 16 bytes we want to be sure that the queue
176 * is full before we read. In the other cases we are ok if the
177 * queue has data available
179 if (dwNumWords == 4) {
180 if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) {
181 /* Clear the Avail/Full bits - which ever is set. */
182 value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL));
183 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
186 } else if (dwNumWords == 1) {
187 if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) {
188 /* We just got Avail and we have to read 32bits so we
189 * need this sleep for Cardbus kind of devices.
191 if (Adapter->chip_id == 0xBECE0210)
194 /* Clear the Avail/Full bits - which ever is set. */
195 value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL));
196 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
204 if (dwRetries == 0) {
207 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
208 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
209 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n",
210 dwNumWords, value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY);
211 return STATUS_FAILURE;
214 if (!(dwRetries%RETRIES_PER_DELAY))
218 for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) {
219 /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */
220 pvalue = (PUCHAR)(pdwData + dwIndex);
223 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
228 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
233 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
238 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
243 return STATUS_SUCCESS;
244 } /* ReadBeceemEEPROMBulk() */
247 * Procedure: ReadBeceemEEPROM
249 * Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page
250 * reads to do this operation.
253 * Adapter - ptr to Adapter object instance
254 * uiOffset - EEPROM Offset to read the data from.
255 * pBuffer - Pointer to word where data needs to be stored in.
261 int ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter,
265 unsigned int uiData[8] = {0};
266 unsigned int uiByteOffset = 0;
267 unsigned int uiTempOffset = 0;
269 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ====> ");
271 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
272 uiByteOffset = uiOffset - uiTempOffset;
274 ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
276 /* A word can overlap at most over 2 pages. In that case we read the
279 if (uiByteOffset > 12)
280 ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
282 memcpy((PUCHAR)pBuffer, (((PUCHAR)&uiData[0]) + uiByteOffset), 4);
284 return STATUS_SUCCESS;
285 } /* ReadBeceemEEPROM() */
287 int ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter)
290 unsigned char puMacAddr[6];
292 Status = BeceemNVMRead(Adapter,
293 (PUINT)&puMacAddr[0],
294 INIT_PARAMS_1_MACADDRESS_ADDRESS,
297 if (Status == STATUS_SUCCESS)
298 memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
304 * Procedure: BeceemEEPROMBulkRead
306 * Description: Reads the EEPROM and returns the Data.
309 * Adapter - ptr to Adapter object instance
310 * pBuffer - Buffer to store the data read from EEPROM
311 * uiOffset - Offset of EEPROM from where data should be read
312 * uiNumBytes - Number of bytes to be read from the EEPROM.
315 * OSAL_STATUS_SUCCESS - if EEPROM read is successful.
316 * <FAILURE> - if failed.
319 int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter,
321 unsigned int uiOffset,
322 unsigned int uiNumBytes)
324 unsigned int uiData[4] = {0};
325 /* unsigned int uiAddress = 0; */
326 unsigned int uiBytesRemaining = uiNumBytes;
327 unsigned int uiIndex = 0;
328 unsigned int uiTempOffset = 0;
329 unsigned int uiExtraBytes = 0;
330 unsigned int uiFailureRetries = 0;
331 PUCHAR pcBuff = (PUCHAR)pBuffer;
333 if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) {
334 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
335 uiExtraBytes = uiOffset - uiTempOffset;
336 ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
337 if (uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) {
338 memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), MAX_RW_SIZE - uiExtraBytes);
339 uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes);
340 uiIndex += (MAX_RW_SIZE - uiExtraBytes);
341 uiOffset += (MAX_RW_SIZE - uiExtraBytes);
343 memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), uiBytesRemaining);
344 uiIndex += uiBytesRemaining;
345 uiOffset += uiBytesRemaining;
346 uiBytesRemaining = 0;
350 while (uiBytesRemaining && uiFailureRetries != 128) {
351 if (Adapter->device_removed)
354 if (uiBytesRemaining >= MAX_RW_SIZE) {
355 /* For the requests more than or equal to 16 bytes, use bulk
356 * read function to make the access faster.
357 * We read 4 Dwords of data
359 if (ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4) == 0) {
360 memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE);
361 uiOffset += MAX_RW_SIZE;
362 uiBytesRemaining -= MAX_RW_SIZE;
363 uiIndex += MAX_RW_SIZE;
366 mdelay(3); /* sleep for a while before retry... */
368 } else if (uiBytesRemaining >= 4) {
369 if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) {
370 memcpy(pcBuff + uiIndex, &uiData[0], 4);
372 uiBytesRemaining -= 4;
376 mdelay(3); /* sleep for a while before retry... */
379 /* Handle the reads less than 4 bytes... */
380 PUCHAR pCharBuff = (PUCHAR)pBuffer;
382 pCharBuff += uiIndex;
383 if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) {
384 memcpy(pCharBuff, &uiData[0], uiBytesRemaining); /* copy only bytes requested. */
385 uiBytesRemaining = 0;
388 mdelay(3); /* sleep for a while before retry... */
397 * Procedure: BeceemFlashBulkRead
399 * Description: Reads the FLASH and returns the Data.
402 * Adapter - ptr to Adapter object instance
403 * pBuffer - Buffer to store the data read from FLASH
404 * uiOffset - Offset of FLASH from where data should be read
405 * uiNumBytes - Number of bytes to be read from the FLASH.
408 * OSAL_STATUS_SUCCESS - if FLASH read is successful.
409 * <FAILURE> - if failed.
412 static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter,
414 unsigned int uiOffset,
415 unsigned int uiNumBytes)
417 unsigned int uiIndex = 0;
418 unsigned int uiBytesToRead = uiNumBytes;
420 unsigned int uiPartOffset = 0;
423 if (Adapter->device_removed) {
424 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed");
428 /* Adding flash Base address
429 * uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
431 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
432 Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
436 Adapter->SelectedChip = RESET_CHIP_SELECT;
438 if (uiOffset % MAX_RW_SIZE) {
439 BcmDoChipSelect(Adapter, uiOffset);
440 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
442 uiBytesToRead = MAX_RW_SIZE - (uiOffset % MAX_RW_SIZE);
443 uiBytesToRead = MIN(uiNumBytes, uiBytesToRead);
445 bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
448 Adapter->SelectedChip = RESET_CHIP_SELECT;
452 uiIndex += uiBytesToRead;
453 uiOffset += uiBytesToRead;
454 uiNumBytes -= uiBytesToRead;
458 BcmDoChipSelect(Adapter, uiOffset);
459 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
461 uiBytesToRead = MIN(uiNumBytes, MAX_RW_SIZE);
463 bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
469 uiIndex += uiBytesToRead;
470 uiOffset += uiBytesToRead;
471 uiNumBytes -= uiBytesToRead;
473 Adapter->SelectedChip = RESET_CHIP_SELECT;
478 * Procedure: BcmGetFlashSize
480 * Description: Finds the size of FLASH.
483 * Adapter - ptr to Adapter object instance
486 * unsigned int - size of the FLASH Storage.
490 static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter)
492 if (IsFlash2x(Adapter))
493 return Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header);
499 * Procedure: BcmGetEEPROMSize
501 * Description: Finds the size of EEPROM.
504 * Adapter - ptr to Adapter object instance
507 * unsigned int - size of the EEPROM Storage.
511 static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter)
513 unsigned int uiData = 0;
514 unsigned int uiIndex = 0;
517 * if EEPROM is present and already Calibrated,it will have
518 * 'BECM' string at 0th offset.
519 * To find the EEPROM size read the possible boundaries of the
520 * EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will
521 * result in wrap around. So when we get the End of the EEPROM we will
522 * get 'BECM' string which is indeed at offset 0.
524 BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4);
525 if (uiData == BECM) {
526 for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) {
527 BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4);
529 return uiIndex * 1024;
533 * EEPROM may not be present or not programmed
536 if (BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE) == 0) {
538 for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) {
539 BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4);
540 if (uiData == 0xBABEFACE)
541 return uiIndex * 1024;
549 * Procedure: FlashSectorErase
551 * Description: Finds the sector size of the FLASH.
554 * Adapter - ptr to Adapter object instance
555 * addr - sector start address
556 * numOfSectors - number of sectors to be erased.
563 static int FlashSectorErase(struct bcm_mini_adapter *Adapter,
565 unsigned int numOfSectors)
567 unsigned int iIndex = 0, iRetries = 0;
568 unsigned int uiStatus = 0;
572 for (iIndex = 0; iIndex < numOfSectors; iIndex++) {
574 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
576 value = (0xd8000000 | (addr & 0xFFFFFF));
577 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
581 value = (FLASH_CMD_STATUS_REG_READ << 24);
582 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
583 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
584 return STATUS_FAILURE;
587 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
590 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
594 /* After every try lets make the CPU free for 10 ms. generally time taken by the
595 * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms
596 * won't hamper performance in any case.
599 } while ((uiStatus & 0x1) && (iRetries < 400));
601 if (uiStatus & 0x1) {
602 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "iRetries crossing the limit of 80000\n");
603 return STATUS_FAILURE;
606 addr += Adapter->uiSectorSize;
611 * Procedure: flashByteWrite
613 * Description: Performs Byte by Byte write to flash
616 * Adapter - ptr to Adapter object instance
617 * uiOffset - Offset of the flash where data needs to be written to.
618 * pData - Address of Data to be written.
624 static int flashByteWrite(struct bcm_mini_adapter *Adapter,
625 unsigned int uiOffset,
628 unsigned int uiStatus = 0;
629 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
631 ULONG ulData = *(PUCHAR)pData;
634 * need not write 0xFF because write requires an erase and erase will
635 * make whole sector 0xFF.
639 return STATUS_SUCCESS;
641 /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */
642 value = (FLASH_CMD_WRITE_ENABLE << 24);
643 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
644 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails");
645 return STATUS_FAILURE;
648 if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) {
649 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails");
650 return STATUS_FAILURE;
652 value = (0x02000000 | (uiOffset & 0xFFFFFF));
653 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
654 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails");
655 return STATUS_FAILURE;
661 value = (FLASH_CMD_STATUS_REG_READ << 24);
662 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
663 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
664 return STATUS_FAILURE;
667 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
670 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
674 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
677 } while ((uiStatus & 0x1) && (iRetries > 0));
679 if (uiStatus & 0x1) {
680 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
681 return STATUS_FAILURE;
684 return STATUS_SUCCESS;
688 * Procedure: flashWrite
690 * Description: Performs write to flash
693 * Adapter - ptr to Adapter object instance
694 * uiOffset - Offset of the flash where data needs to be written to.
695 * pData - Address of Data to be written.
701 static int flashWrite(struct bcm_mini_adapter *Adapter,
702 unsigned int uiOffset,
705 /* unsigned int uiStatus = 0;
707 * unsigned int uiReadBack = 0;
709 unsigned int uiStatus = 0;
710 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
712 unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
715 * need not write 0xFFFFFFFF because write requires an erase and erase will
716 * make whole sector 0xFFFFFFFF.
718 if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
721 value = (FLASH_CMD_WRITE_ENABLE << 24);
723 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
724 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails");
725 return STATUS_FAILURE;
728 if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) {
729 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails...");
730 return STATUS_FAILURE;
735 value = (FLASH_CMD_STATUS_REG_READ << 24);
736 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
737 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
738 return STATUS_FAILURE;
741 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
744 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
749 /* this will ensure that in there will be no changes in the current path.
750 * currently one rdm/wrm takes 125 us.
751 * Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay)
752 * Hence current implementation cycle will intoduce no delay in current path
754 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
756 } while ((uiStatus & 0x1) && (iRetries > 0));
758 if (uiStatus & 0x1) {
759 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
760 return STATUS_FAILURE;
763 return STATUS_SUCCESS;
766 /*-----------------------------------------------------------------------------
767 * Procedure: flashByteWriteStatus
769 * Description: Performs byte by byte write to flash with write done status check
772 * Adapter - ptr to Adapter object instance
773 * uiOffset - Offset of the flash where data needs to be written to.
774 * pData - Address of the Data to be written.
779 static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter,
780 unsigned int uiOffset,
783 unsigned int uiStatus = 0;
784 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
785 ULONG ulData = *(PUCHAR)pData;
790 * need not write 0xFFFFFFFF because write requires an erase and erase will
791 * make whole sector 0xFFFFFFFF.
795 return STATUS_SUCCESS;
797 /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */
799 value = (FLASH_CMD_WRITE_ENABLE << 24);
800 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
801 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails");
802 return STATUS_SUCCESS;
804 if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) {
805 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails");
806 return STATUS_FAILURE;
808 value = (0x02000000 | (uiOffset & 0xFFFFFF));
809 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
810 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails");
811 return STATUS_FAILURE;
817 value = (FLASH_CMD_STATUS_REG_READ << 24);
818 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
819 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
820 return STATUS_FAILURE;
823 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
826 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
831 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
834 } while ((uiStatus & 0x1) && (iRetries > 0));
836 if (uiStatus & 0x1) {
837 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
838 return STATUS_FAILURE;
841 return STATUS_SUCCESS;
844 * Procedure: flashWriteStatus
846 * Description: Performs write to flash with write done status check
849 * Adapter - ptr to Adapter object instance
850 * uiOffset - Offset of the flash where data needs to be written to.
851 * pData - Address of the Data to be written.
857 static int flashWriteStatus(struct bcm_mini_adapter *Adapter,
858 unsigned int uiOffset,
861 unsigned int uiStatus = 0;
862 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
863 /* unsigned int uiReadBack = 0; */
865 unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
869 * need not write 0xFFFFFFFF because write requires an erase and erase will
870 * make whole sector 0xFFFFFFFF.
872 if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
875 value = (FLASH_CMD_WRITE_ENABLE << 24);
876 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
877 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails");
878 return STATUS_FAILURE;
881 if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) {
882 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails...");
883 return STATUS_FAILURE;
888 value = (FLASH_CMD_STATUS_REG_READ << 24);
889 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
890 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
891 return STATUS_FAILURE;
894 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
897 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
901 /* this will ensure that in there will be no changes in the current path.
902 * currently one rdm/wrm takes 125 us.
903 * Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay)
904 * Hence current implementation cycle will intoduce no delay in current path
906 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
909 } while ((uiStatus & 0x1) && (iRetries > 0));
911 if (uiStatus & 0x1) {
912 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
913 return STATUS_FAILURE;
916 return STATUS_SUCCESS;
920 * Procedure: BcmRestoreBlockProtectStatus
922 * Description: Restores the original block protection status.
925 * Adapter - ptr to Adapter object instance
926 * ulWriteStatus -Original status
932 static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus)
936 value = (FLASH_CMD_WRITE_ENABLE << 24);
937 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
940 value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
941 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
946 * Procedure: BcmFlashUnProtectBlock
948 * Description: UnProtects appropriate blocks for writing.
951 * Adapter - ptr to Adapter object instance
952 * uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned.
954 * ULONG - Status value before UnProtect.
958 static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned int uiOffset, unsigned int uiLength)
961 ULONG ulWriteStatus = 0;
964 uiOffset = uiOffset&0x000FFFFF;
966 * Implemented only for 1MB Flash parts.
968 if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) {
970 * Get Current BP status.
972 value = (FLASH_CMD_STATUS_REG_READ << 24);
973 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
976 * Read status will be WWXXYYZZ. We have to take only WW.
978 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
980 ulWriteStatus = ulStatus;
982 * Bits [5-2] give current block level protection status.
983 * Bit5: BP3 - DONT CARE
984 * BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4
985 * 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS
989 if ((uiOffset+uiLength) <= 0x80000) {
991 * Offset comes in lower half of 1MB. Protect the upper half.
992 * Clear BP1 and BP0 and set BP2.
994 ulWriteStatus |= (0x4<<2);
995 ulWriteStatus &= ~(0x3<<2);
996 } else if ((uiOffset + uiLength) <= 0xC0000) {
998 * Offset comes below Upper 1/4. Upper 1/4 can be protected.
999 * Clear BP2 and set BP1 and BP0.
1001 ulWriteStatus |= (0x3<<2);
1002 ulWriteStatus &= ~(0x1<<4);
1003 } else if ((uiOffset + uiLength) <= 0xE0000) {
1005 * Offset comes below Upper 1/8. Upper 1/8 can be protected.
1006 * Clear BP2 and BP0 and set BP1
1008 ulWriteStatus |= (0x1<<3);
1009 ulWriteStatus &= ~(0x5<<2);
1010 } else if ((uiOffset + uiLength) <= 0xF0000) {
1012 * Offset comes below Upper 1/16. Only upper 1/16 can be protected.
1013 * Set BP0 and Clear BP2,BP1.
1015 ulWriteStatus |= (0x1<<2);
1016 ulWriteStatus &= ~(0x3<<3);
1020 * Clear BP2,BP1 and BP0.
1022 ulWriteStatus &= ~(0x7<<2);
1025 value = (FLASH_CMD_WRITE_ENABLE << 24);
1026 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1028 value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
1029 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1036 static int bulk_read_complete_sector(struct bcm_mini_adapter *ad,
1039 unsigned int offset,
1040 unsigned int partoff)
1045 FP_FLASH_WRITE_STATUS writef =
1046 ad->fpFlashWriteWithStatusCheck;
1048 for (i = 0; i < ad->uiSectorSize; i += MAX_RW_SIZE) {
1049 bulk_read_stat = BeceemFlashBulkRead(ad,
1054 if (bulk_read_stat != STATUS_SUCCESS)
1057 if (ad->ulFlashWriteSize == 1) {
1058 for (j = 0; j < 16; j++) {
1059 if ((read_bk[j] != tmpbuff[i + j]) &&
1060 (STATUS_SUCCESS != (*writef)(ad, partoff + i + j, &tmpbuff[i + j]))) {
1061 return STATUS_FAILURE;
1065 if ((memcmp(read_bk, &tmpbuff[i], MAX_RW_SIZE)) &&
1066 (STATUS_SUCCESS != (*writef)(ad, partoff + i, &tmpbuff[i]))) {
1067 return STATUS_FAILURE;
1072 return STATUS_SUCCESS;
1076 * Procedure: BeceemFlashBulkWrite
1078 * Description: Performs write to the flash
1081 * Adapter - ptr to Adapter object instance
1082 * pBuffer - Data to be written.
1083 * uiOffset - Offset of the flash where data needs to be written to.
1084 * uiNumBytes - Number of bytes to be written.
1085 * bVerify - read verify flag.
1091 static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter,
1093 unsigned int uiOffset,
1094 unsigned int uiNumBytes,
1097 PCHAR pTempBuff = NULL;
1098 PUCHAR pcBuffer = (PUCHAR)pBuffer;
1099 unsigned int uiIndex = 0;
1100 unsigned int uiOffsetFromSectStart = 0;
1101 unsigned int uiSectAlignAddr = 0;
1102 unsigned int uiCurrSectOffsetAddr = 0;
1103 unsigned int uiSectBoundary = 0;
1104 unsigned int uiNumSectTobeRead = 0;
1105 UCHAR ucReadBk[16] = {0};
1107 int Status = STATUS_SUCCESS;
1108 unsigned int uiTemp = 0;
1109 unsigned int index = 0;
1110 unsigned int uiPartOffset = 0;
1112 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1113 Status = bcmflash_raw_write((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
1117 uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
1119 /* Adding flash Base address
1120 * uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
1123 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
1124 uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
1125 uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
1127 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
1129 goto BeceemFlashBulkWrite_EXIT;
1131 * check if the data to be written is overlapped across sectors
1133 if (uiOffset+uiNumBytes < uiSectBoundary) {
1134 uiNumSectTobeRead = 1;
1136 /* Number of sectors = Last sector start address/First sector start address */
1137 uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize;
1138 if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize)
1139 uiNumSectTobeRead++;
1141 /* Check whether Requested sector is writable or not in case of flash2x write. But if write call is
1142 * for DSD calibration, allow it without checking of sector permission
1145 if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) {
1147 uiTemp = uiNumSectTobeRead;
1149 if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) {
1150 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%X> is not writable",
1151 (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
1152 Status = SECTOR_IS_NOT_WRITABLE;
1153 goto BeceemFlashBulkWrite_EXIT;
1155 uiTemp = uiTemp - 1;
1159 Adapter->SelectedChip = RESET_CHIP_SELECT;
1160 while (uiNumSectTobeRead) {
1161 /* do_gettimeofday(&tv1);
1162 * 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));
1164 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1166 BcmDoChipSelect(Adapter, uiSectAlignAddr);
1168 if (0 != BeceemFlashBulkRead(Adapter,
1170 uiOffsetFromSectStart,
1171 Adapter->uiSectorSize)) {
1173 goto BeceemFlashBulkWrite_EXIT;
1176 /* do_gettimeofday(&tr);
1177 * 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));
1179 ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
1181 if (uiNumSectTobeRead > 1) {
1182 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1183 pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)));
1184 uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1186 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes);
1189 if (IsFlash2x(Adapter))
1190 SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart);
1192 FlashSectorErase(Adapter, uiPartOffset, 1);
1193 /* do_gettimeofday(&te);
1194 * 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));
1196 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) {
1197 if (Adapter->device_removed) {
1199 goto BeceemFlashBulkWrite_EXIT;
1202 if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) {
1204 goto BeceemFlashBulkWrite_EXIT;
1208 /* do_gettimeofday(&tw);
1209 * 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));
1212 if (STATUS_FAILURE == bulk_read_complete_sector(Adapter,
1215 uiOffsetFromSectStart,
1217 Status = STATUS_FAILURE;
1218 goto BeceemFlashBulkWrite_EXIT;
1221 /* do_gettimeofday(&twv);
1222 * 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));
1225 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1229 uiCurrSectOffsetAddr = 0;
1230 uiSectAlignAddr = uiSectBoundary;
1231 uiSectBoundary += Adapter->uiSectorSize;
1232 uiOffsetFromSectStart += Adapter->uiSectorSize;
1233 uiNumSectTobeRead--;
1235 /* do_gettimeofday(&tv2);
1236 * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000));
1237 * 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));
1241 BeceemFlashBulkWrite_EXIT:
1243 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1247 Adapter->SelectedChip = RESET_CHIP_SELECT;
1252 * Procedure: BeceemFlashBulkWriteStatus
1254 * Description: Writes to Flash. Checks the SPI status after each write.
1257 * Adapter - ptr to Adapter object instance
1258 * pBuffer - Data to be written.
1259 * uiOffset - Offset of the flash where data needs to be written to.
1260 * uiNumBytes - Number of bytes to be written.
1261 * bVerify - read verify flag.
1267 static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter,
1269 unsigned int uiOffset,
1270 unsigned int uiNumBytes,
1273 PCHAR pTempBuff = NULL;
1274 PUCHAR pcBuffer = (PUCHAR)pBuffer;
1275 unsigned int uiIndex = 0;
1276 unsigned int uiOffsetFromSectStart = 0;
1277 unsigned int uiSectAlignAddr = 0;
1278 unsigned int uiCurrSectOffsetAddr = 0;
1279 unsigned int uiSectBoundary = 0;
1280 unsigned int uiNumSectTobeRead = 0;
1281 UCHAR ucReadBk[16] = {0};
1283 unsigned int Status = STATUS_SUCCESS;
1284 unsigned int uiTemp = 0;
1285 unsigned int index = 0;
1286 unsigned int uiPartOffset = 0;
1288 uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
1290 /* uiOffset += Adapter->ulFlashCalStart;
1291 * Adding flash Base address
1292 * uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
1294 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
1295 uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
1296 uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
1298 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
1300 goto BeceemFlashBulkWriteStatus_EXIT;
1303 * check if the data to be written is overlapped across sectors
1305 if (uiOffset+uiNumBytes < uiSectBoundary) {
1306 uiNumSectTobeRead = 1;
1308 /* Number of sectors = Last sector start address/First sector start address */
1309 uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize;
1310 if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize)
1311 uiNumSectTobeRead++;
1314 if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == false)) {
1316 uiTemp = uiNumSectTobeRead;
1318 if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == false) {
1319 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%x> is not writable",
1320 (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
1321 Status = SECTOR_IS_NOT_WRITABLE;
1322 goto BeceemFlashBulkWriteStatus_EXIT;
1324 uiTemp = uiTemp - 1;
1329 Adapter->SelectedChip = RESET_CHIP_SELECT;
1330 while (uiNumSectTobeRead) {
1331 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1333 BcmDoChipSelect(Adapter, uiSectAlignAddr);
1334 if (0 != BeceemFlashBulkRead(Adapter,
1336 uiOffsetFromSectStart,
1337 Adapter->uiSectorSize)) {
1339 goto BeceemFlashBulkWriteStatus_EXIT;
1342 ulStatus = BcmFlashUnProtectBlock(Adapter, uiOffsetFromSectStart, Adapter->uiSectorSize);
1344 if (uiNumSectTobeRead > 1) {
1345 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1346 pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)));
1347 uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1349 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes);
1352 if (IsFlash2x(Adapter))
1353 SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart);
1355 FlashSectorErase(Adapter, uiPartOffset, 1);
1357 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) {
1358 if (Adapter->device_removed) {
1360 goto BeceemFlashBulkWriteStatus_EXIT;
1363 if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) {
1365 goto BeceemFlashBulkWriteStatus_EXIT;
1370 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) {
1371 if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) {
1372 if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) {
1373 Status = STATUS_FAILURE;
1374 goto BeceemFlashBulkWriteStatus_EXIT;
1381 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1385 uiCurrSectOffsetAddr = 0;
1386 uiSectAlignAddr = uiSectBoundary;
1387 uiSectBoundary += Adapter->uiSectorSize;
1388 uiOffsetFromSectStart += Adapter->uiSectorSize;
1389 uiNumSectTobeRead--;
1394 BeceemFlashBulkWriteStatus_EXIT:
1396 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1399 Adapter->SelectedChip = RESET_CHIP_SELECT;
1404 * Procedure: PropagateCalParamsFromFlashToMemory
1406 * Description: Dumps the calibration section of EEPROM to DDR.
1409 * Adapter - ptr to Adapter object instance
1415 int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter)
1418 unsigned int uiEepromSize = 0;
1419 unsigned int uiBytesToCopy = 0;
1420 /* unsigned int uiIndex = 0; */
1421 unsigned int uiCalStartAddr = EEPROM_CALPARAM_START;
1422 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1427 * Write the signature first. This will ensure firmware does not access EEPROM.
1430 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
1432 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
1434 if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4))
1437 uiEepromSize = ntohl(uiEepromSize);
1438 uiEepromSize >>= 16;
1441 * subtract the auto init section size
1443 uiEepromSize -= EEPROM_CALPARAM_START;
1445 if (uiEepromSize > 1024 * 1024)
1448 pBuff = kmalloc(uiEepromSize, GFP_KERNEL);
1452 if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) {
1459 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
1461 while (uiBytesToCopy) {
1462 Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy);
1464 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status);
1468 pPtr += uiBytesToCopy;
1469 uiEepromSize -= uiBytesToCopy;
1470 uiMemoryLoc += uiBytesToCopy;
1471 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
1479 * Procedure: BeceemEEPROMReadBackandVerify
1481 * Description: Read back the data written and verifies.
1484 * Adapter - ptr to Adapter object instance
1485 * pBuffer - Data to be written.
1486 * uiOffset - Offset of the flash where data needs to be written to.
1487 * uiNumBytes - Number of bytes to be written.
1493 static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter,
1495 unsigned int uiOffset,
1496 unsigned int uiNumBytes)
1498 unsigned int uiRdbk = 0;
1499 unsigned int uiIndex = 0;
1500 unsigned int uiData = 0;
1501 unsigned int auiData[4] = {0};
1503 while (uiNumBytes) {
1504 if (Adapter->device_removed)
1507 if (uiNumBytes >= MAX_RW_SIZE) {
1508 /* for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. */
1509 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
1511 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) {
1513 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, false);
1515 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
1517 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE))
1520 uiOffset += MAX_RW_SIZE;
1521 uiNumBytes -= MAX_RW_SIZE;
1523 } else if (uiNumBytes >= 4) {
1524 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
1525 if (uiData != pBuffer[uiIndex]) {
1527 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, false);
1529 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
1530 if (uiData != pBuffer[uiIndex])
1537 /* Handle the reads less than 4 bytes... */
1539 memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(unsigned int)), uiNumBytes);
1540 BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4);
1542 if (memcmp(&uiData, &uiRdbk, uiNumBytes))
1552 static VOID BcmSwapWord(unsigned int *ptr1)
1554 unsigned int tempval = (unsigned int)*ptr1;
1555 char *ptr2 = (char *)&tempval;
1556 char *ptr = (char *)ptr1;
1565 * Procedure: BeceemEEPROMWritePage
1567 * Description: Performs page write (16bytes) to the EEPROM
1570 * Adapter - ptr to Adapter object instance
1571 * uiData - Data to be written.
1572 * uiOffset - Offset of the EEPROM where data needs to be written to.
1578 static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, unsigned int uiData[], unsigned int uiOffset)
1580 unsigned int uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
1581 unsigned int uiStatus = 0;
1582 UCHAR uiEpromStatus = 0;
1583 unsigned int value = 0;
1585 /* Flush the Write/Read/Cmd queues. */
1586 value = (EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH);
1587 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
1589 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
1591 /* Clear the Empty/Avail/Full bits. After this it has been confirmed
1592 * that the bit was cleared by reading back the register. See NOTE below.
1593 * We also clear the Read queues as we do a EEPROM status register read
1596 value = (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
1597 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
1600 value = EEPROM_WRITE_ENABLE;
1601 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
1603 /* We can write back to back 8bits * 16 into the queue and as we have
1604 * checked for the queue to be empty we can write in a burst.
1608 BcmSwapWord(&value);
1609 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1612 BcmSwapWord(&value);
1613 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1616 BcmSwapWord(&value);
1617 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1620 BcmSwapWord(&value);
1621 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1623 /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG
1624 * shows that we see 7 for the EEPROM data write. Which means that
1625 * queue got full, also space is available as well as the queue is empty.
1626 * This may happen in sequence.
1628 value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset;
1629 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
1631 /* Ideally we should loop here without tries and eventually succeed.
1632 * What we are checking if the previous write has completed, and this
1633 * may take time. We should wait till the Empty bit is set.
1636 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
1637 while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) {
1639 if (uiRetries == 0) {
1640 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY);
1641 return STATUS_FAILURE;
1644 if (!(uiRetries%RETRIES_PER_DELAY))
1648 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
1649 if (Adapter->device_removed == TRUE) {
1650 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop....");
1655 if (uiRetries != 0) {
1656 /* Clear the ones that are set - either, Empty/Full/Avail bits */
1657 value = (uiStatus & (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL));
1658 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
1661 /* Here we should check if the EEPROM status register is correct before
1662 * proceeding. Bit 0 in the EEPROM Status register should be 0 before
1663 * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy
1664 * with the previous write. Note also that issuing this read finally
1665 * means the previous write to the EEPROM has completed.
1667 uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
1669 while (uiRetries != 0) {
1670 uiEpromStatus = ReadEEPROMStatusRegister(Adapter);
1671 if (Adapter->device_removed == TRUE) {
1672 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
1675 if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) {
1676 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY - uiRetries));
1677 return STATUS_SUCCESS;
1680 if (uiRetries == 0) {
1681 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);
1682 return STATUS_FAILURE;
1685 if (!(uiRetries%RETRIES_PER_DELAY))
1689 return STATUS_SUCCESS;
1690 } /* BeceemEEPROMWritePage */
1693 * Procedure: BeceemEEPROMBulkWrite
1695 * Description: Performs write to the EEPROM
1698 * Adapter - ptr to Adapter object instance
1699 * pBuffer - Data to be written.
1700 * uiOffset - Offset of the EEPROM where data needs to be written to.
1701 * uiNumBytes - Number of bytes to be written.
1702 * bVerify - read verify flag.
1708 int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter,
1710 unsigned int uiOffset,
1711 unsigned int uiNumBytes,
1714 unsigned int uiBytesToCopy = uiNumBytes;
1715 /* unsigned int uiRdbk = 0; */
1716 unsigned int uiData[4] = {0};
1717 unsigned int uiIndex = 0;
1718 unsigned int uiTempOffset = 0;
1719 unsigned int uiExtraBytes = 0;
1720 /* PUINT puiBuffer = (PUINT)pBuffer;
1724 if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) {
1725 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
1726 uiExtraBytes = uiOffset - uiTempOffset;
1728 BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE);
1730 if (uiBytesToCopy >= (16 - uiExtraBytes)) {
1731 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes);
1733 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
1734 return STATUS_FAILURE;
1736 uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes);
1737 uiIndex += (MAX_RW_SIZE - uiExtraBytes);
1738 uiOffset += (MAX_RW_SIZE - uiExtraBytes);
1740 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy);
1742 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
1743 return STATUS_FAILURE;
1745 uiIndex += uiBytesToCopy;
1746 uiOffset += uiBytesToCopy;
1751 while (uiBytesToCopy) {
1752 if (Adapter->device_removed)
1755 if (uiBytesToCopy >= MAX_RW_SIZE) {
1756 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset))
1757 return STATUS_FAILURE;
1759 uiIndex += MAX_RW_SIZE;
1760 uiOffset += MAX_RW_SIZE;
1761 uiBytesToCopy -= MAX_RW_SIZE;
1764 * To program non 16byte aligned data, read 16byte and then update.
1766 BeceemEEPROMBulkRead(Adapter, &uiData[0], uiOffset, 16);
1767 memcpy(&uiData[0], pBuffer + uiIndex, uiBytesToCopy);
1769 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiOffset))
1770 return STATUS_FAILURE;
1780 * Procedure: BeceemNVMRead
1782 * Description: Reads n number of bytes from NVM.
1785 * Adapter - ptr to Adapter object instance
1786 * pBuffer - Buffer to store the data read from NVM
1787 * uiOffset - Offset of NVM from where data should be read
1788 * uiNumBytes - Number of bytes to be read from the NVM.
1791 * OSAL_STATUS_SUCCESS - if NVM read is successful.
1792 * <FAILURE> - if failed.
1795 int BeceemNVMRead(struct bcm_mini_adapter *Adapter,
1797 unsigned int uiOffset,
1798 unsigned int uiNumBytes)
1802 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
1803 unsigned int uiTemp = 0, value;
1806 if (Adapter->eNVMType == NVM_FLASH) {
1807 if (Adapter->bFlashRawRead == false) {
1808 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
1809 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes);
1811 uiOffset = uiOffset + Adapter->ulFlashCalStart;
1814 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1815 Status = bcmflash_raw_read((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
1817 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1819 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
1820 Status = BeceemFlashBulkRead(Adapter,
1824 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1826 } else if (Adapter->eNVMType == NVM_EEPROM) {
1827 Status = BeceemEEPROMBulkRead(Adapter,
1839 * Procedure: BeceemNVMWrite
1841 * Description: Writes n number of bytes to NVM.
1844 * Adapter - ptr to Adapter object instance
1845 * pBuffer - Buffer contains the data to be written.
1846 * uiOffset - Offset of NVM where data to be written to.
1847 * uiNumBytes - Number of bytes to be written..
1850 * OSAL_STATUS_SUCCESS - if NVM write is successful.
1851 * <FAILURE> - if failed.
1854 int BeceemNVMWrite(struct bcm_mini_adapter *Adapter,
1856 unsigned int uiOffset,
1857 unsigned int uiNumBytes,
1861 unsigned int uiTemp = 0;
1862 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1863 unsigned int uiIndex = 0;
1865 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
1869 unsigned int uiFlashOffset = 0;
1871 if (Adapter->eNVMType == NVM_FLASH) {
1872 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
1873 Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify);
1875 uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;
1877 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1878 Status = bcmflash_raw_write((uiFlashOffset / FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
1880 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1882 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
1884 if (Adapter->bStatusWrite == TRUE)
1885 Status = BeceemFlashBulkWriteStatus(Adapter,
1892 Status = BeceemFlashBulkWrite(Adapter,
1900 if (uiOffset >= EEPROM_CALPARAM_START) {
1901 uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
1902 while (uiNumBytes) {
1903 if (uiNumBytes > BUFFER_4K) {
1904 wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K);
1905 uiNumBytes -= BUFFER_4K;
1906 uiIndex += BUFFER_4K;
1908 wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes);
1914 if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) {
1915 ULONG ulBytesTobeSkipped = 0;
1916 PUCHAR pcBuffer = (PUCHAR)pBuffer; /* char pointer to take care of odd byte cases. */
1918 uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
1919 ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
1920 uiOffset += (EEPROM_CALPARAM_START - uiOffset);
1921 while (uiNumBytes) {
1922 if (uiNumBytes > BUFFER_4K) {
1923 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K);
1924 uiNumBytes -= BUFFER_4K;
1925 uiIndex += BUFFER_4K;
1927 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes);
1934 /* restore the values. */
1935 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1936 } else if (Adapter->eNVMType == NVM_EEPROM) {
1937 Status = BeceemEEPROMBulkWrite(Adapter,
1943 Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes);
1951 * Procedure: BcmUpdateSectorSize
1953 * Description: Updates the sector size to FLASH.
1956 * Adapter - ptr to Adapter object instance
1957 * uiSectorSize - sector size
1960 * OSAL_STATUS_SUCCESS - if NVM write is successful.
1961 * <FAILURE> - if failed.
1964 int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, unsigned int uiSectorSize)
1967 struct bcm_flash_cs_info sFlashCsInfo = {0};
1968 unsigned int uiTemp = 0;
1969 unsigned int uiSectorSig = 0;
1970 unsigned int uiCurrentSectorSize = 0;
1973 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1975 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
1978 * Before updating the sector size in the reserved area, check if already present.
1980 BeceemFlashBulkRead(Adapter, (PUINT)&sFlashCsInfo, Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo));
1981 uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
1982 uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);
1984 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
1985 if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) {
1986 if (uiSectorSize == uiCurrentSectorSize) {
1987 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash");
1988 Status = STATUS_SUCCESS;
1994 if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) {
1995 sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize);
1996 sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG);
1998 Status = BeceemFlashBulkWrite(Adapter,
1999 (PUINT)&sFlashCsInfo,
2000 Adapter->ulFlashControlSectionStart,
2001 sizeof(sFlashCsInfo),
2006 /* restore the values. */
2007 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2013 * Procedure: BcmGetFlashSectorSize
2015 * Description: Finds the sector size of the FLASH.
2018 * Adapter - ptr to Adapter object instance
2021 * unsigned int - sector size.
2025 static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize)
2027 unsigned int uiSectorSize = 0;
2028 unsigned int uiSectorSig = 0;
2030 if (Adapter->bSectorSizeOverride &&
2031 (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2032 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) {
2033 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2035 uiSectorSig = FlashSectorSizeSig;
2037 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
2038 uiSectorSize = FlashSectorSize;
2040 * If the sector size stored in the FLASH makes sense then use it.
2042 if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) {
2043 Adapter->uiSectorSize = uiSectorSize;
2044 } else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2045 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) {
2046 /* No valid size in FLASH, check if Config file has it. */
2047 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2049 /* Init to Default, if none of the above works. */
2050 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2053 if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2054 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
2055 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2057 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2061 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x\n", Adapter->uiSectorSize);
2063 return Adapter->uiSectorSize;
2067 * Procedure: BcmInitEEPROMQueues
2069 * Description: Initialization of EEPROM queues.
2072 * Adapter - ptr to Adapter object instance
2075 * <OSAL_STATUS_CODE>
2078 static int BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter)
2080 unsigned int value = 0;
2081 /* CHIP Bug : Clear the Avail bits on the Read queue. The default
2082 * value on this register is supposed to be 0x00001102.
2083 * But we get 0x00001122.
2085 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n");
2086 value = EEPROM_READ_DATA_AVAIL;
2087 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
2089 /* Flush the all the EEPROM queues. */
2090 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n");
2091 value = EEPROM_ALL_QUEUE_FLUSH;
2092 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
2095 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
2097 /* Read the EEPROM Status Register. Just to see, no real purpose. */
2098 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter));
2100 return STATUS_SUCCESS;
2101 } /* BcmInitEEPROMQueues() */
2104 * Procedure: BcmInitNVM
2106 * Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc.
2109 * Adapter - ptr to Adapter object instance
2112 * <OSAL_STATUS_CODE>
2115 int BcmInitNVM(struct bcm_mini_adapter *ps_adapter)
2117 BcmValidateNvmType(ps_adapter);
2118 BcmInitEEPROMQueues(ps_adapter);
2120 if (ps_adapter->eNVMType == NVM_AUTODETECT) {
2121 ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
2122 if (ps_adapter->eNVMType == NVM_UNKNOWN)
2123 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
2124 } else if (ps_adapter->eNVMType == NVM_FLASH) {
2125 BcmGetFlashCSInfo(ps_adapter);
2128 BcmGetNvmSize(ps_adapter);
2130 return STATUS_SUCCESS;
2133 /* BcmGetNvmSize : set the EEPROM or flash size in Adapter.
2136 * Adapter data structure
2141 static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter)
2143 if (Adapter->eNVMType == NVM_EEPROM)
2144 Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
2145 else if (Adapter->eNVMType == NVM_FLASH)
2146 Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
2152 * Procedure: BcmValidateNvm
2154 * Description: Validates the NVM Type option selected against the device
2157 * Adapter - ptr to Adapter object instance
2163 static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter)
2166 * if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
2167 * Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
2168 * So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
2171 if (Adapter->eNVMType == NVM_FLASH &&
2172 Adapter->chip_id < 0xBECE3300)
2173 Adapter->eNVMType = NVM_AUTODETECT;
2177 * Procedure: BcmReadFlashRDID
2179 * Description: Reads ID from Serial Flash
2182 * Adapter - ptr to Adapter object instance
2188 static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter)
2194 * Read ID Instruction.
2196 value = (FLASH_CMD_READ_ID << 24);
2197 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
2203 * Read SPI READQ REG. The output will be WWXXYYZZ.
2204 * The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
2206 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID));
2211 int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
2214 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
2217 psAdapter->psFlashCSInfo = kzalloc(sizeof(struct bcm_flash_cs_info), GFP_KERNEL);
2218 if (psAdapter->psFlashCSInfo == NULL) {
2219 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x");
2223 psAdapter->psFlash2xCSInfo = kzalloc(sizeof(struct bcm_flash2x_cs_info), GFP_KERNEL);
2224 if (!psAdapter->psFlash2xCSInfo) {
2225 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x");
2226 kfree(psAdapter->psFlashCSInfo);
2230 psAdapter->psFlash2xVendorInfo = kzalloc(sizeof(struct bcm_flash2x_vendor_info), GFP_KERNEL);
2231 if (!psAdapter->psFlash2xVendorInfo) {
2232 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x");
2233 kfree(psAdapter->psFlashCSInfo);
2234 kfree(psAdapter->psFlash2xCSInfo);
2238 return STATUS_SUCCESS;
2241 int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
2244 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
2247 kfree(psAdapter->psFlashCSInfo);
2248 kfree(psAdapter->psFlash2xCSInfo);
2249 kfree(psAdapter->psFlash2xVendorInfo);
2250 return STATUS_SUCCESS;
2253 static int BcmDumpFlash2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo, struct bcm_mini_adapter *Adapter)
2255 unsigned int Index = 0;
2257 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
2258 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber));
2259 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2260 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2261 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
2262 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
2263 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
2264 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
2265 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware));
2266 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
2267 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
2268 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
2269 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
2270 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
2271 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
2272 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
2273 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
2274 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
2275 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
2276 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
2277 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
2278 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
2279 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
2280 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
2281 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
2282 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
2283 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
2284 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
2285 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
2286 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
2287 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
2288 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
2289 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
2290 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
2291 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
2292 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
2293 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
2294 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
2295 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
2296 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
2297 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
2298 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
2299 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
2300 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
2301 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
2302 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
2303 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
2304 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
2306 for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++)
2307 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
2308 (psFlash2xCSInfo->SectorAccessBitMap[Index]));
2310 return STATUS_SUCCESS;
2313 static int ConvertEndianOf2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo)
2315 unsigned int Index = 0;
2317 psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
2318 psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion);
2319 /* psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); */
2320 psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
2321 psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
2322 psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
2323 psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
2324 psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware);
2325 psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
2326 psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
2327 psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
2328 psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
2329 psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
2330 psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
2331 psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
2332 psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
2333 psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
2334 psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
2335 psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
2336 psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
2337 psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
2338 psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
2339 psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
2340 psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
2341 psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
2342 psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
2343 psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
2344 psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
2345 psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
2346 psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
2347 psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
2348 psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
2349 psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
2350 psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
2351 psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
2352 psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
2353 psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
2354 psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
2355 psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
2356 psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
2357 psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
2358 psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
2359 psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
2360 psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
2361 psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
2362 psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
2364 for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++)
2365 psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
2367 return STATUS_SUCCESS;
2370 static int ConvertEndianOfCSStructure(struct bcm_flash_cs_info *psFlashCSInfo)
2372 /* unsigned int Index = 0; */
2373 psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber);
2374 psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion);
2375 psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion);
2376 /* won't convert according to old assumption */
2377 psFlashCSInfo->SCSIFirmwareVersion = (psFlashCSInfo->SCSIFirmwareVersion);
2378 psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
2379 psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
2380 psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware);
2381 psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
2382 psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2383 psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
2384 psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
2385 psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
2386 psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
2387 psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
2388 psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout);
2389 psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature);
2390 psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig);
2391 psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize);
2392 psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize);
2393 psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize);
2394 psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr);
2395 psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize);
2396 psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
2397 psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout);
2399 return STATUS_SUCCESS;
2402 static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
2404 return (Adapter->uiVendorExtnFlag &&
2405 (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
2406 (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS));
2409 static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter)
2412 unsigned int uiSizeSection = 0;
2414 Adapter->uiVendorExtnFlag = false;
2416 for (i = 0; i < TOTAL_SECTIONS; i++)
2417 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
2419 if (STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
2423 while (i < TOTAL_SECTIONS) {
2424 if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) {
2429 Adapter->uiVendorExtnFlag = TRUE;
2430 uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
2431 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
2435 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
2436 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2437 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
2439 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
2443 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
2444 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2445 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
2447 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
2451 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
2452 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2453 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
2455 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
2458 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2459 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
2461 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
2465 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2466 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
2468 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
2471 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2472 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
2474 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
2485 * Procedure: BcmGetFlashCSInfo
2487 * Description: Reads control structure and gets Cal section addresses.
2490 * Adapter - ptr to Adapter object instance
2496 static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter)
2498 /* struct bcm_flash_cs_info sFlashCsInfo = {0}; */
2500 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2504 unsigned int uiFlashLayoutMajorVersion;
2506 Adapter->uiFlashLayoutMinorVersion = 0;
2507 Adapter->uiFlashLayoutMajorVersion = 0;
2508 Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
2510 Adapter->uiFlashBaseAdd = 0;
2511 Adapter->ulFlashCalStart = 0;
2512 memset(Adapter->psFlashCSInfo, 0 , sizeof(struct bcm_flash_cs_info));
2513 memset(Adapter->psFlash2xCSInfo, 0 , sizeof(struct bcm_flash2x_cs_info));
2515 if (!Adapter->bDDRInitDone) {
2516 value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
2517 wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
2520 /* Reading first 8 Bytes to get the Flash Layout
2521 * MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
2523 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8);
2525 Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
2526 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
2527 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); */
2528 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));
2530 if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) {
2531 uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2532 Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2534 Adapter->uiFlashLayoutMinorVersion = 0;
2535 uiFlashLayoutMajorVersion = 0;
2538 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);
2540 if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) {
2541 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash_cs_info));
2542 ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
2543 Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2545 if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
2546 Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
2548 if ((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) &&
2549 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) &&
2550 (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) &&
2551 (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) {
2552 Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
2553 Adapter->fpFlashWrite = flashByteWrite;
2554 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2556 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2557 Adapter->fpFlashWrite = flashWrite;
2558 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2561 BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
2562 (Adapter->psFlashCSInfo->FlashSectorSize));
2563 Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2565 if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL,
2566 Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash2x_cs_info))) {
2567 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n");
2568 return STATUS_FAILURE;
2571 ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
2572 BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo, Adapter);
2573 if ((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
2574 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
2575 (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
2576 (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) {
2577 Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
2578 Adapter->fpFlashWrite = flashByteWrite;
2579 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2581 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2582 Adapter->fpFlashWrite = flashWrite;
2583 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2586 BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
2587 Adapter->psFlash2xCSInfo->FlashSectorSize);
2589 UpdateVendorInfo(Adapter);
2591 BcmGetActiveDSD(Adapter);
2592 BcmGetActiveISO(Adapter);
2593 Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2594 Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;
2597 * Concerns: what if CS sector size does not match with this sector size ???
2598 * what is the indication of AccessBitMap in CS in flash 2.x ????
2600 Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
2601 Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
2603 return STATUS_SUCCESS;
2607 * Procedure: BcmGetNvmType
2609 * Description: Finds the type of NVM used.
2612 * Adapter - ptr to Adapter object instance
2619 static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter)
2621 unsigned int uiData = 0;
2623 BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4);
2628 * Read control struct and get cal addresses before accessing the flash
2630 BcmGetFlashCSInfo(Adapter);
2632 BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4);
2637 * even if there is no valid signature on EEPROM/FLASH find out if they really exist.
2638 * if exist select it.
2640 if (BcmGetEEPROMSize(Adapter))
2643 /* TBD for Flash. */
2648 * BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
2649 * @Adapter : Drivers Private Data structure
2650 * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
2653 * On success it return the start offset of the provided section val
2654 * On Failure -returns STATUS_FAILURE
2657 int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
2660 * Considering all the section for which end offset can be calculated or directly given
2661 * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
2662 * endoffset can't be calculated or given in CS Structure.
2665 int SectStartOffset = 0;
2667 SectStartOffset = INVALID_OFFSET;
2669 if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal))
2670 return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
2672 switch (eFlashSectionVal) {
2674 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
2675 (IsNonCDLessDevice(Adapter) == false))
2676 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
2679 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
2680 (IsNonCDLessDevice(Adapter) == false))
2681 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
2684 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
2685 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
2688 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
2689 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
2692 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
2693 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
2696 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
2697 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
2700 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
2701 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
2704 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
2705 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
2708 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
2709 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
2711 case CONTROL_SECTION:
2712 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
2713 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
2715 case ISO_IMAGE1_PART2:
2716 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
2717 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
2719 case ISO_IMAGE1_PART3:
2720 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
2721 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
2723 case ISO_IMAGE2_PART2:
2724 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
2725 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
2727 case ISO_IMAGE2_PART3:
2728 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
2729 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
2732 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
2733 SectStartOffset = INVALID_OFFSET;
2736 return SectStartOffset;
2740 * BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
2741 * @Adapter : Drivers Private Data structure
2742 * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
2745 * On success it return the end offset of the provided section val
2746 * On Failure -returns STATUS_FAILURE
2749 static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
2751 int SectEndOffset = 0;
2753 SectEndOffset = INVALID_OFFSET;
2754 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
2755 return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
2757 switch (eFlash2xSectionVal) {
2759 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) &&
2760 (IsNonCDLessDevice(Adapter) == false))
2761 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
2764 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) &&
2765 (IsNonCDLessDevice(Adapter) == false))
2766 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
2769 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
2770 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
2773 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
2774 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
2777 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
2778 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
2781 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
2782 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
2785 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
2786 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
2789 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
2790 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
2793 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
2794 SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
2795 (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
2797 case CONTROL_SECTION:
2798 /* Not Clear So Putting failure. confirm and fix it. */
2799 SectEndOffset = STATUS_FAILURE;
2801 case ISO_IMAGE1_PART2:
2802 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS)
2803 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
2805 case ISO_IMAGE1_PART3:
2806 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS)
2807 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
2809 case ISO_IMAGE2_PART2:
2810 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
2811 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
2813 case ISO_IMAGE2_PART3:
2814 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS)
2815 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
2818 SectEndOffset = INVALID_OFFSET;
2821 return SectEndOffset;
2825 * BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
2826 * @Adapter :Driver Private Data Structure
2827 * @pBuffer : Buffer where data has to be put after reading
2828 * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
2829 * @uiOffsetWithinSectionVal :- Offset with in provided section
2830 * @uiNumBytes : Number of Bytes for Read
2833 * return true on success and STATUS_FAILURE on fail.
2836 int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
2838 enum bcm_flash2x_section_val eFlash2xSectionVal,
2839 unsigned int uiOffsetWithinSectionVal,
2840 unsigned int uiNumBytes)
2842 int Status = STATUS_SUCCESS;
2843 int SectionStartOffset = 0;
2844 unsigned int uiAbsoluteOffset = 0;
2845 unsigned int uiTemp = 0, value = 0;
2848 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
2851 if (Adapter->device_removed) {
2852 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
2856 /* NO_SECTION_VAL means absolute offset is given. */
2857 if (eFlash2xSectionVal == NO_SECTION_VAL)
2858 SectionStartOffset = 0;
2860 SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
2862 if (SectionStartOffset == STATUS_FAILURE) {
2863 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash 2.x Map ", eFlash2xSectionVal);
2867 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
2868 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
2870 /* calculating the absolute offset from FLASH; */
2871 uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
2872 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2874 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2875 Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes);
2876 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2878 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
2886 * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
2887 * @Adapter :Driver Private Data Structure
2888 * @pBuffer : Buffer From where data has to taken for writing
2889 * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
2890 * @uiOffsetWithinSectionVal :- Offset with in provided section
2891 * @uiNumBytes : Number of Bytes for Write
2894 * return true on success and STATUS_FAILURE on fail.
2898 int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
2900 enum bcm_flash2x_section_val eFlash2xSectVal,
2901 unsigned int uiOffset,
2902 unsigned int uiNumBytes,
2903 unsigned int bVerify)
2905 int Status = STATUS_SUCCESS;
2906 unsigned int FlashSectValStartOffset = 0;
2907 unsigned int uiTemp = 0, value = 0;
2910 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
2914 if (Adapter->device_removed) {
2915 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
2919 /* NO_SECTION_VAL means absolute offset is given. */
2920 if (eFlash2xSectVal == NO_SECTION_VAL)
2921 FlashSectValStartOffset = 0;
2923 FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal);
2925 if (FlashSectValStartOffset == STATUS_FAILURE) {
2926 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash Map 2.x", eFlash2xSectVal);
2930 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal))
2931 return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
2933 /* calculating the absolute offset from FLASH; */
2934 uiOffset = uiOffset + FlashSectValStartOffset;
2936 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2938 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2940 Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify);
2942 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2944 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
2952 * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
2953 * @Adapter :-Drivers private Data Structure
2956 * Return STATUS_SUCESS if get success in setting the right DSD else negative error code
2960 static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter)
2962 enum bcm_flash2x_section_val uiHighestPriDSD = 0;
2964 uiHighestPriDSD = getHighestPriDSD(Adapter);
2965 Adapter->eActiveDSD = uiHighestPriDSD;
2967 if (DSD0 == uiHighestPriDSD)
2968 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
2969 if (DSD1 == uiHighestPriDSD)
2970 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
2971 if (DSD2 == uiHighestPriDSD)
2972 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
2973 if (Adapter->eActiveDSD)
2974 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
2975 if (Adapter->eActiveDSD == 0) {
2976 /* if No DSD gets Active, Make Active the DSD with WR permission */
2977 if (IsSectionWritable(Adapter, DSD2)) {
2978 Adapter->eActiveDSD = DSD2;
2979 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
2980 } else if (IsSectionWritable(Adapter, DSD1)) {
2981 Adapter->eActiveDSD = DSD1;
2982 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
2983 } else if (IsSectionWritable(Adapter, DSD0)) {
2984 Adapter->eActiveDSD = DSD0;
2985 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
2989 return STATUS_SUCCESS;
2993 * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
2994 * @Adapter : Driver private Data Structure
2997 * Sucsess:- STATUS_SUCESS
2998 * Failure- : negative erro code
3002 static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter)
3004 int HighestPriISO = 0;
3006 HighestPriISO = getHighestPriISO(Adapter);
3008 Adapter->eActiveISO = HighestPriISO;
3009 if (Adapter->eActiveISO == ISO_IMAGE2)
3010 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
3011 else if (Adapter->eActiveISO == ISO_IMAGE1)
3012 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3014 if (Adapter->eActiveISO)
3015 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO);
3017 return STATUS_SUCCESS;
3021 * IsOffsetWritable :- it will tell the access permission of the sector having passed offset
3022 * @Adapter : Drivers Private Data Structure
3023 * @uiOffset : Offset provided in the Flash
3026 * Success:-TRUE , offset is writable
3027 * Failure:-false, offset is RO
3031 static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset)
3033 unsigned int uiSectorNum = 0;
3034 unsigned int uiWordOfSectorPermission = 0;
3035 unsigned int uiBitofSectorePermission = 0;
3036 B_UINT32 permissionBits = 0;
3038 uiSectorNum = uiOffset/Adapter->uiSectorSize;
3040 /* calculating the word having this Sector Access permission from SectorAccessBitMap Array */
3041 uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16];
3043 /* calculating the bit index inside the word for this sector */
3044 uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16);
3046 /* Setting Access permission */
3047 permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission);
3048 permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
3049 if (permissionBits == SECTOR_READWRITE_PERMISSION)
3055 static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap)
3057 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
3059 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
3060 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1);
3061 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2);
3062 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD0 :0X%x", psFlash2xBitMap->DSD0);
3063 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD1 :0X%x", psFlash2xBitMap->DSD1);
3064 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD2 :0X%x", psFlash2xBitMap->DSD2);
3065 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA0 :0X%x", psFlash2xBitMap->VSA0);
3066 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA1 :0X%x", psFlash2xBitMap->VSA1);
3067 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA2 :0X%x", psFlash2xBitMap->VSA2);
3068 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSI :0X%x", psFlash2xBitMap->SCSI);
3069 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION);
3071 return STATUS_SUCCESS;
3075 * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
3076 * 8bit has been assigned to every section.
3077 * bit[0] :Section present or not
3078 * bit[1] :section is valid or not
3079 * bit[2] : Secton is read only or has write permission too.
3080 * bit[3] : Active Section -
3081 * bit[7...4] = Reserved .
3083 * @Adapter:-Driver private Data Structure
3086 * Success:- STATUS_SUCESS
3087 * Failure:- negative error code
3090 int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap)
3092 struct bcm_flash2x_cs_info *psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
3093 enum bcm_flash2x_section_val uiHighestPriDSD = 0;
3094 enum bcm_flash2x_section_val uiHighestPriISO = 0;
3095 bool SetActiveDSDDone = false;
3096 bool SetActiveISODone = false;
3098 /* For 1.x map all the section except DSD0 will be shown as not present
3099 * This part will be used by calibration tool to detect the number of DSD present in Flash.
3101 if (IsFlash2x(Adapter) == false) {
3102 psFlash2xBitMap->ISO_IMAGE2 = 0;
3103 psFlash2xBitMap->ISO_IMAGE1 = 0;
3104 psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */
3105 psFlash2xBitMap->DSD1 = 0;
3106 psFlash2xBitMap->DSD2 = 0;
3107 psFlash2xBitMap->VSA0 = 0;
3108 psFlash2xBitMap->VSA1 = 0;
3109 psFlash2xBitMap->VSA2 = 0;
3110 psFlash2xBitMap->CONTROL_SECTION = 0;
3111 psFlash2xBitMap->SCSI = 0;
3112 psFlash2xBitMap->Reserved0 = 0;
3113 psFlash2xBitMap->Reserved1 = 0;
3114 psFlash2xBitMap->Reserved2 = 0;
3116 return STATUS_SUCCESS;
3119 uiHighestPriDSD = getHighestPriDSD(Adapter);
3120 uiHighestPriISO = getHighestPriISO(Adapter);
3125 if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) {
3126 /* Setting the 0th Bit representing the Section is present or not. */
3127 psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
3129 if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER)
3130 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
3132 /* Calculation for extrating the Access permission */
3133 if (IsSectionWritable(Adapter, ISO_IMAGE2) == false)
3134 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
3136 if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE2) {
3137 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT;
3138 SetActiveISODone = TRUE;
3145 if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) {
3146 /* Setting the 0th Bit representing the Section is present or not. */
3147 psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
3149 if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
3150 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
3152 /* Calculation for extrating the Access permission */
3153 if (IsSectionWritable(Adapter, ISO_IMAGE1) == false)
3154 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
3156 if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE1) {
3157 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT;
3158 SetActiveISODone = TRUE;
3165 if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) {
3166 /* Setting the 0th Bit representing the Section is present or not. */
3167 psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
3169 if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER)
3170 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
3172 /* Calculation for extrating the Access permission */
3173 if (IsSectionWritable(Adapter, DSD2) == false) {
3174 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
3176 /* Means section is writable */
3177 if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD2)) {
3178 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT;
3179 SetActiveDSDDone = TRUE;
3187 if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) {
3188 /* Setting the 0th Bit representing the Section is present or not. */
3189 psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
3191 if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER)
3192 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
3194 /* Calculation for extrating the Access permission */
3195 if (IsSectionWritable(Adapter, DSD1) == false) {
3196 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
3198 /* Means section is writable */
3199 if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD1)) {
3200 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT;
3201 SetActiveDSDDone = TRUE;
3209 if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) {
3210 /* Setting the 0th Bit representing the Section is present or not. */
3211 psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
3213 if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER)
3214 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
3216 /* Setting Access permission */
3217 if (IsSectionWritable(Adapter, DSD0) == false) {
3218 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
3220 /* Means section is writable */
3221 if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD0)) {
3222 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT;
3223 SetActiveDSDDone = TRUE;
3231 if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) {
3232 /* Setting the 0th Bit representing the Section is present or not. */
3233 psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
3235 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3236 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
3238 /* Calculation for extrating the Access permission */
3239 if (IsSectionWritable(Adapter, VSA0) == false)
3240 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO;
3242 /* By Default section is Active */
3243 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT;
3249 if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) {
3250 /* Setting the 0th Bit representing the Section is present or not. */
3251 psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
3253 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3254 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID;
3256 /* Checking For Access permission */
3257 if (IsSectionWritable(Adapter, VSA1) == false)
3258 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
3260 /* By Default section is Active */
3261 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT;
3267 if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) {
3268 /* Setting the 0th Bit representing the Section is present or not. */
3269 psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
3271 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3272 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
3274 /* Checking For Access permission */
3275 if (IsSectionWritable(Adapter, VSA2) == false)
3276 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
3278 /* By Default section is Active */
3279 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT;
3285 if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) {
3286 /* Setting the 0th Bit representing the Section is present or not. */
3287 psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
3289 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3290 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID;
3292 /* Checking For Access permission */
3293 if (IsSectionWritable(Adapter, SCSI) == false)
3294 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
3296 /* By Default section is Active */
3297 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT;
3303 if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) {
3304 /* Setting the 0th Bit representing the Section is present or not. */
3305 psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
3307 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3308 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
3310 /* Checking For Access permission */
3311 if (IsSectionWritable(Adapter, CONTROL_SECTION) == false)
3312 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
3314 /* By Default section is Active */
3315 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT;
3319 * For Reserved Sections
3321 psFlash2xBitMap->Reserved0 = 0;
3322 psFlash2xBitMap->Reserved0 = 0;
3323 psFlash2xBitMap->Reserved0 = 0;
3324 BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
3326 return STATUS_SUCCESS;
3330 * BcmSetActiveSection :- Set Active section is used to make priority field highest over other
3331 * section of same type.
3333 * @Adapater :- Bcm Driver Private Data Structure
3334 * @eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
3336 * Return Value:- Make the priorit highest else return erorr code
3340 int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal)
3342 unsigned int SectImagePriority = 0;
3343 int Status = STATUS_SUCCESS;
3345 /* struct bcm_dsd_header sDSD = {0};
3346 * struct bcm_iso_header sISO = {0};
3348 int HighestPriDSD = 0;
3349 int HighestPriISO = 0;
3351 Status = IsSectionWritable(Adapter, eFlash2xSectVal);
3352 if (Status != TRUE) {
3353 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal);
3354 return STATUS_FAILURE;
3357 Adapter->bHeaderChangeAllowed = TRUE;
3358 switch (eFlash2xSectVal) {
3361 if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) {
3362 HighestPriISO = getHighestPriISO(Adapter);
3364 if (HighestPriISO == eFlash2xSectVal) {
3365 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
3366 Status = STATUS_SUCCESS;
3370 SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
3372 if ((SectImagePriority == 0) && IsSectionWritable(Adapter, HighestPriISO)) {
3373 /* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
3374 * We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
3377 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
3378 SectImagePriority = htonl(0x1);
3379 Status = BcmFlash2xBulkWrite(Adapter,
3382 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
3386 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3387 Status = STATUS_FAILURE;
3391 HighestPriISO = getHighestPriISO(Adapter);
3393 if (HighestPriISO == eFlash2xSectVal) {
3394 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
3395 Status = STATUS_SUCCESS;
3399 SectImagePriority = 2;
3402 SectImagePriority = htonl(SectImagePriority);
3404 Status = BcmFlash2xBulkWrite(Adapter,
3407 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
3411 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3415 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3416 Status = STATUS_FAILURE;
3423 if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) {
3424 HighestPriDSD = getHighestPriDSD(Adapter);
3425 if (HighestPriDSD == eFlash2xSectVal) {
3426 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal);
3427 Status = STATUS_SUCCESS;
3431 SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1;
3432 if (SectImagePriority == 0) {
3433 /* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
3434 * We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
3437 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
3438 SectImagePriority = htonl(0x1);
3440 Status = BcmFlash2xBulkWrite(Adapter,
3443 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
3447 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3451 HighestPriDSD = getHighestPriDSD(Adapter);
3453 if (HighestPriDSD == eFlash2xSectVal) {
3454 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
3455 Status = STATUS_SUCCESS;
3459 SectImagePriority = htonl(0x2);
3460 Status = BcmFlash2xBulkWrite(Adapter,
3463 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
3467 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3471 HighestPriDSD = getHighestPriDSD(Adapter);
3472 if (HighestPriDSD == eFlash2xSectVal) {
3473 Status = STATUS_SUCCESS;
3477 SectImagePriority = 3;
3479 SectImagePriority = htonl(SectImagePriority);
3480 Status = BcmFlash2xBulkWrite(Adapter,
3483 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
3487 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3488 Status = STATUS_FAILURE;
3492 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3493 Status = STATUS_FAILURE;
3500 /* Has to be decided */
3503 Status = STATUS_FAILURE;
3507 Adapter->bHeaderChangeAllowed = false;
3512 * BcmCopyISO - Used only for copying the ISO section
3513 * @Adapater :- Bcm Driver Private Data Structure
3514 * @sCopySectStrut :- Section copy structure
3516 * Return value:- SUCCESS if copies successfully else negative error code
3520 int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut)
3523 enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0;
3524 unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
3525 unsigned int uiTotalDataToCopy = 0;
3526 bool IsThisHeaderSector = false;
3527 unsigned int sigOffset = 0;
3528 unsigned int ISOLength = 0;
3529 unsigned int Status = STATUS_SUCCESS;
3530 unsigned int SigBuff[MAX_RW_SIZE];
3533 if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) {
3534 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3535 return STATUS_FAILURE;
3538 Status = BcmFlash2xBulkRead(Adapter, &ISOLength,
3539 sCopySectStrut.SrcSection,
3540 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize),
3543 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
3547 ISOLength = htonl(ISOLength);
3548 if (ISOLength % Adapter->uiSectorSize)
3549 ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize);
3551 sigOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber);
3553 Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
3556 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size");
3560 if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) {
3561 eISOReadPart = ISO_IMAGE1;
3562 eISOWritePart = ISO_IMAGE2;
3563 uiReadOffsetWithinPart = 0;
3564 uiWriteOffsetWithinPart = 0;
3566 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
3567 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
3568 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
3569 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
3570 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
3571 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3573 if (uiTotalDataToCopy < ISOLength) {
3574 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3575 Status = STATUS_FAILURE;
3579 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
3580 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
3581 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
3582 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
3583 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
3584 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3586 if (uiTotalDataToCopy < ISOLength) {
3587 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
3588 Status = STATUS_FAILURE;
3592 uiTotalDataToCopy = ISOLength;
3594 CorruptISOSig(Adapter, ISO_IMAGE2);
3595 while (uiTotalDataToCopy) {
3596 if (uiTotalDataToCopy == Adapter->uiSectorSize) {
3597 /* Setting for write of first sector. First sector is assumed to be written in last */
3598 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
3599 eISOReadPart = ISO_IMAGE1;
3600 uiReadOffsetWithinPart = 0;
3601 eISOWritePart = ISO_IMAGE2;
3602 uiWriteOffsetWithinPart = 0;
3603 IsThisHeaderSector = TRUE;
3605 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3606 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
3608 if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
3609 eISOReadPart = ISO_IMAGE1_PART2;
3610 uiReadOffsetWithinPart = 0;
3613 if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
3614 eISOReadPart = ISO_IMAGE1_PART3;
3615 uiReadOffsetWithinPart = 0;
3618 if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
3619 eISOWritePart = ISO_IMAGE2_PART2;
3620 uiWriteOffsetWithinPart = 0;
3623 if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
3624 eISOWritePart = ISO_IMAGE2_PART3;
3625 uiWriteOffsetWithinPart = 0;
3629 Status = BcmFlash2xBulkRead(Adapter,
3632 uiReadOffsetWithinPart,
3633 Adapter->uiSectorSize);
3635 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
3639 if (IsThisHeaderSector == TRUE) {
3640 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
3641 memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff));
3643 for (i = 0; i < MAX_RW_SIZE; i++)
3644 *(Buff + sigOffset + i) = 0xFF;
3646 Adapter->bHeaderChangeAllowed = TRUE;
3647 Status = BcmFlash2xBulkWrite(Adapter,
3650 uiWriteOffsetWithinPart,
3651 Adapter->uiSectorSize,
3654 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
3658 Adapter->bHeaderChangeAllowed = false;
3659 if (IsThisHeaderSector == TRUE) {
3660 WriteToFlashWithoutSectorErase(Adapter,
3665 IsThisHeaderSector = false;
3667 /* subtracting the written Data */
3668 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
3672 if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) {
3673 eISOReadPart = ISO_IMAGE2;
3674 eISOWritePart = ISO_IMAGE1;
3675 uiReadOffsetWithinPart = 0;
3676 uiWriteOffsetWithinPart = 0;
3678 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
3679 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
3680 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
3681 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
3682 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
3683 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3685 if (uiTotalDataToCopy < ISOLength) {
3686 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3687 Status = STATUS_FAILURE;
3691 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
3692 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
3693 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
3694 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
3695 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
3696 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3698 if (uiTotalDataToCopy < ISOLength) {
3699 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
3700 Status = STATUS_FAILURE;
3704 uiTotalDataToCopy = ISOLength;
3706 CorruptISOSig(Adapter, ISO_IMAGE1);
3708 while (uiTotalDataToCopy) {
3709 if (uiTotalDataToCopy == Adapter->uiSectorSize) {
3710 /* Setting for write of first sector. First sector is assumed to be written in last */
3711 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
3712 eISOReadPart = ISO_IMAGE2;
3713 uiReadOffsetWithinPart = 0;
3714 eISOWritePart = ISO_IMAGE1;
3715 uiWriteOffsetWithinPart = 0;
3716 IsThisHeaderSector = TRUE;
3718 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3719 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
3721 if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
3722 eISOReadPart = ISO_IMAGE2_PART2;
3723 uiReadOffsetWithinPart = 0;
3726 if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
3727 eISOReadPart = ISO_IMAGE2_PART3;
3728 uiReadOffsetWithinPart = 0;
3731 if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
3732 eISOWritePart = ISO_IMAGE1_PART2;
3733 uiWriteOffsetWithinPart = 0;
3736 if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
3737 eISOWritePart = ISO_IMAGE1_PART3;
3738 uiWriteOffsetWithinPart = 0;
3742 Status = BcmFlash2xBulkRead(Adapter,
3745 uiReadOffsetWithinPart,
3746 Adapter->uiSectorSize);
3748 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
3752 if (IsThisHeaderSector == TRUE) {
3753 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
3754 memcpy(SigBuff, Buff + sigOffset, sizeof(SigBuff));
3756 for (i = 0; i < MAX_RW_SIZE; i++)
3757 *(Buff + sigOffset + i) = 0xFF;
3759 Adapter->bHeaderChangeAllowed = TRUE;
3760 Status = BcmFlash2xBulkWrite(Adapter,
3763 uiWriteOffsetWithinPart,
3764 Adapter->uiSectorSize,
3767 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
3771 Adapter->bHeaderChangeAllowed = false;
3772 if (IsThisHeaderSector == TRUE) {
3773 WriteToFlashWithoutSectorErase(Adapter,
3779 IsThisHeaderSector = false;
3782 /* subtracting the written Data */
3783 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
3793 * BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
3794 * It will corrupt the sig, if Section is writable, by making first bytes as zero.
3795 * @Adapater :- Bcm Driver Private Data Structure
3796 * @eFlash2xSectionVal :- Flash section val which has header
3799 * Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
3800 * Failure :-Return negative error code
3803 int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
3805 int Status = STATUS_SUCCESS;
3807 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal);
3809 if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) {
3810 Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
3811 } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) {
3812 Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
3814 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal);
3815 return STATUS_SUCCESS;
3821 *BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
3822 * header and Write Permission.
3823 * @Adapater :- Bcm Driver Private Data Structure
3824 * @eFlashSectionVal :- Flash section val which has header
3827 * Success :- If Section is present and writable write the sig and return STATUS_SUCCESS
3828 * Failure :-Return negative error code
3831 int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
3833 unsigned int uiSignature = 0;
3834 unsigned int uiOffset = 0;
3836 /* struct bcm_dsd_header dsdHeader = {0}; */
3837 if (Adapter->bSigCorrupted == false) {
3838 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n");
3839 return STATUS_SUCCESS;
3842 if (Adapter->bAllDSDWriteAllow == false) {
3843 if (IsSectionWritable(Adapter, eFlashSectionVal) == false) {
3844 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature");
3845 return SECTOR_IS_NOT_WRITABLE;
3849 if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) {
3850 uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER);
3851 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader;
3853 uiOffset += FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber);
3855 if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
3856 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig");
3857 return STATUS_FAILURE;
3859 } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) {
3860 uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
3862 uiOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber);
3863 if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
3864 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig");
3865 return STATUS_FAILURE;
3868 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
3869 return STATUS_FAILURE;
3872 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature");
3874 Adapter->bHeaderChangeAllowed = TRUE;
3875 Adapter->bSigCorrupted = false;
3876 BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE);
3877 Adapter->bHeaderChangeAllowed = false;
3879 return STATUS_SUCCESS;
3883 * validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
3884 * if requested Bytes goes beyond the Requested section, it reports error.
3885 * @Adapater :- Bcm Driver Private Data Structure
3886 * @psFlash2xReadWrite :-Flash2x Read/write structure pointer
3888 * Return values:-Return TRUE is request is valid else false.
3891 int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite)
3893 unsigned int uiNumOfBytes = 0;
3894 unsigned int uiSectStartOffset = 0;
3895 unsigned int uiSectEndOffset = 0;
3897 uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
3899 if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) {
3900 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exist in Flash", psFlash2xReadWrite->Section);
3903 uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section);
3904 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section);
3905 if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) {
3906 if (psFlash2xReadWrite->Section == ISO_IMAGE1) {
3907 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) -
3908 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) +
3909 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) -
3910 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) +
3911 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) -
3912 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3);
3913 } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) {
3914 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) -
3915 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) +
3916 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) -
3917 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART2) +
3918 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART3) -
3919 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3);
3922 /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset
3923 * it should be added in startoffset. so that check done in last of this function can be valued.
3925 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset;
3927 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset);
3929 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section);
3931 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset);
3933 /* psFlash2xReadWrite->offset and uiNumOfBytes are user controlled and can lead to integer overflows */
3934 if (psFlash2xReadWrite->offset > uiSectEndOffset) {
3935 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
3938 if (uiNumOfBytes > uiSectEndOffset) {
3939 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
3942 /* Checking the boundary condition */
3943 if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
3946 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
3952 * IsFlash2x :- check for Flash 2.x
3953 * Adapater :- Bcm Driver Private Data Structure
3956 * return TRUE if flah2.x of hgher version else return false.
3959 int IsFlash2x(struct bcm_mini_adapter *Adapter)
3961 if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
3968 * GetFlashBaseAddr :- Calculate the Flash Base address
3969 * @Adapater :- Bcm Driver Private Data Structure
3972 * Success :- Base Address of the Flash
3975 static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
3977 unsigned int uiBaseAddr = 0;
3979 if (Adapter->bDDRInitDone) {
3981 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3982 * In case of Raw Read... use the default value
3984 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) &&
3985 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
3986 uiBaseAddr = Adapter->uiFlashBaseAdd;
3988 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
3991 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3992 * In case of Raw Read... use the default value
3994 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) &&
3995 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
3996 uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
3998 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4005 * BcmCopySection :- This API is used to copy the One section in another. Both section should
4006 * be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
4008 * @Adapater :- Bcm Driver Private Data Structure
4009 * @SrcSection :- Source section From where data has to be copied
4010 * @DstSection :- Destination section to which data has to be copied
4011 * @offset :- Offset from/to where data has to be copied from one section to another.
4012 * @numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
4013 * in case of numofBytes equal zero complete section will be copied.
4015 * Success : Return STATUS_SUCCESS
4016 * Faillure :- return negative error code
4019 int BcmCopySection(struct bcm_mini_adapter *Adapter,
4020 enum bcm_flash2x_section_val SrcSection,
4021 enum bcm_flash2x_section_val DstSection,
4022 unsigned int offset,
4023 unsigned int numOfBytes)
4025 unsigned int BuffSize = 0;
4026 unsigned int BytesToBeCopied = 0;
4027 PUCHAR pBuff = NULL;
4028 int Status = STATUS_SUCCESS;
4030 if (SrcSection == DstSection) {
4031 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again");
4035 if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) {
4036 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection");
4040 if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) {
4041 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection");
4045 /* if offset zero means have to copy complete secton */
4046 if (numOfBytes == 0) {
4047 numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection)
4048 - BcmGetSectionValStartOffset(Adapter, SrcSection);
4050 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes);
4053 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection)
4054 - BcmGetSectionValStartOffset(Adapter, SrcSection)) {
4055 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
4056 offset, numOfBytes);
4060 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection)
4061 - BcmGetSectionValStartOffset(Adapter, DstSection)) {
4062 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
4063 offset, numOfBytes);
4067 if (numOfBytes > Adapter->uiSectorSize)
4068 BuffSize = Adapter->uiSectorSize;
4070 BuffSize = numOfBytes;
4072 pBuff = kzalloc(BuffSize, GFP_KERNEL);
4074 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. ");
4078 BytesToBeCopied = Adapter->uiSectorSize;
4079 if (offset % Adapter->uiSectorSize)
4080 BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
4081 if (BytesToBeCopied > numOfBytes)
4082 BytesToBeCopied = numOfBytes;
4084 Adapter->bHeaderChangeAllowed = TRUE;
4087 Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied);
4089 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied);
4092 Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, false);
4094 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied);
4097 offset = offset + BytesToBeCopied;
4098 numOfBytes = numOfBytes - BytesToBeCopied;
4100 if (numOfBytes > Adapter->uiSectorSize)
4101 BytesToBeCopied = Adapter->uiSectorSize;
4103 BytesToBeCopied = numOfBytes;
4105 } while (numOfBytes > 0);
4108 Adapter->bHeaderChangeAllowed = false;
4114 * SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
4115 * @Adapater :- Bcm Driver Private Data Structure
4116 * @pBuff :- Data buffer that has to be written in sector having the header map.
4117 * @uiOffset :- Flash offset that has to be written.
4120 * Success :- On success return STATUS_SUCCESS
4121 * Faillure :- Return negative error code
4124 static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset)
4126 unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0;
4127 bool bHasHeader = false;
4128 PUCHAR pTempBuff = NULL;
4129 unsigned int uiSectAlignAddr = 0;
4130 unsigned int sig = 0;
4132 /* making the offset sector aligned */
4133 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4135 if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) ||
4136 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) ||
4137 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) {
4138 /* offset from the sector boundary having the header map */
4139 offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
4140 HeaderSizeToProtect = sizeof(struct bcm_dsd_header);
4144 if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) ||
4145 uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) {
4146 offsetToProtect = 0;
4147 HeaderSizeToProtect = sizeof(struct bcm_iso_header);
4150 /* If Header is present overwrite passed buffer with this */
4151 if (bHasHeader && (Adapter->bHeaderChangeAllowed == false)) {
4152 pTempBuff = kzalloc(HeaderSizeToProtect, GFP_KERNEL);
4154 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed");
4158 BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect);
4159 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect);
4160 /* Replace Buffer content with Header */
4161 memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect);
4165 if (bHasHeader && Adapter->bSigCorrupted) {
4166 sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber)));
4168 if ((sig & 0xFF000000) != CORRUPTED_PATTERN) {
4169 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore");
4170 Adapter->bSigCorrupted = false;
4171 return STATUS_SUCCESS;
4173 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig);
4174 *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER);
4175 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only");
4176 Adapter->bSigCorrupted = false;
4179 return STATUS_SUCCESS;
4183 * BcmDoChipSelect : This will selcet the appropriate chip for writing.
4184 * @Adapater :- Bcm Driver Private Data Structure
4187 * Select the Appropriate chip and retrn status Success
4189 static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset)
4191 unsigned int FlashConfig = 0;
4193 unsigned int GPIOConfig = 0;
4194 unsigned int PartNum = 0;
4196 ChipNum = offset / FLASH_PART_SIZE;
4199 * Chip Select mapping to enable flash0.
4200 * To select flash 0, we have to OR with (0<<12).
4201 * ORing 0 will have no impact so not doing that part.
4202 * In future if Chip select value changes from 0 to non zero,
4203 * That needs be taken care with backward comaptibility. No worries for now.
4207 * SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
4208 * if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
4209 * Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
4210 * power down modes (Idle mode/shutdown mode), the values in the register will be different.
4213 if (Adapter->SelectedChip == ChipNum)
4214 return STATUS_SUCCESS;
4216 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); */
4217 Adapter->SelectedChip = ChipNum;
4219 /* bit[13..12] will select the appropriate chip */
4220 rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4221 rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4229 GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
4233 GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
4237 GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
4241 /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
4242 * nothing to do... can return immediately.
4243 * ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
4244 * Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
4245 * These values are not written by host other than during CHIP_SELECT.
4247 if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
4248 return STATUS_SUCCESS;
4250 /* clearing the bit[13..12] */
4251 FlashConfig &= 0xFFFFCFFF;
4252 FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); /* 00 */
4254 wrmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4257 wrmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4260 return STATUS_SUCCESS;
4263 static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
4265 unsigned int uiDSDsig = 0;
4266 /* unsigned int sigoffsetInMap = 0;
4267 * struct bcm_dsd_header dsdHeader = {0};
4270 /* sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader; */
4272 if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) {
4273 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for DSDs");
4274 return STATUS_FAILURE;
4276 BcmFlash2xBulkRead(Adapter,
4279 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber),
4282 uiDSDsig = ntohl(uiDSDsig);
4283 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig);
4288 static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
4290 /* unsigned int priOffsetInMap = 0 ; */
4291 unsigned int uiDSDPri = STATUS_FAILURE;
4292 /* struct bcm_dsd_header dsdHeader = {0};
4293 * priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
4295 if (IsSectionWritable(Adapter, dsd)) {
4296 if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) {
4297 BcmFlash2xBulkRead(Adapter,
4300 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
4303 uiDSDPri = ntohl(uiDSDPri);
4304 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri);
4311 static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
4313 int DSDHighestPri = STATUS_FAILURE;
4315 enum bcm_flash2x_section_val HighestPriDSD = 0;
4317 if (IsSectionWritable(Adapter, DSD2)) {
4318 DSDHighestPri = ReadDSDPriority(Adapter, DSD2);
4319 HighestPriDSD = DSD2;
4322 if (IsSectionWritable(Adapter, DSD1)) {
4323 DsdPri = ReadDSDPriority(Adapter, DSD1);
4324 if (DSDHighestPri < DsdPri) {
4325 DSDHighestPri = DsdPri;
4326 HighestPriDSD = DSD1;
4330 if (IsSectionWritable(Adapter, DSD0)) {
4331 DsdPri = ReadDSDPriority(Adapter, DSD0);
4332 if (DSDHighestPri < DsdPri) {
4333 DSDHighestPri = DsdPri;
4334 HighestPriDSD = DSD0;
4338 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri);
4340 return HighestPriDSD;
4343 static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
4345 unsigned int uiISOsig = 0;
4346 /* unsigned int sigoffsetInMap = 0;
4347 * struct bcm_iso_header ISOHeader = {0};
4348 * sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
4350 if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) {
4351 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs");
4352 return STATUS_FAILURE;
4354 BcmFlash2xBulkRead(Adapter,
4357 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber),
4360 uiISOsig = ntohl(uiISOsig);
4361 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig);
4366 static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
4368 unsigned int ISOPri = STATUS_FAILURE;
4370 if (IsSectionWritable(Adapter, iso)) {
4371 if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) {
4372 BcmFlash2xBulkRead(Adapter,
4375 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
4378 ISOPri = ntohl(ISOPri);
4379 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri);
4386 static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
4388 int ISOHighestPri = STATUS_FAILURE;
4390 enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL;
4392 if (IsSectionWritable(Adapter, ISO_IMAGE2)) {
4393 ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2);
4394 HighestPriISO = ISO_IMAGE2;
4397 if (IsSectionWritable(Adapter, ISO_IMAGE1)) {
4398 ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1);
4399 if (ISOHighestPri < ISOPri) {
4400 ISOHighestPri = ISOPri;
4401 HighestPriISO = ISO_IMAGE1;
4405 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest ISO :%x and its Pri :%x", HighestPriISO, ISOHighestPri);
4407 return HighestPriISO;
4410 static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
4412 enum bcm_flash2x_section_val eFlash2xSectionVal,
4413 unsigned int uiOffset,
4414 unsigned int uiNumBytes)
4416 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
4417 unsigned int uiTemp = 0, value = 0;
4419 unsigned int uiPartOffset = 0;
4421 unsigned int uiStartOffset = 0;
4422 /* Adding section start address */
4423 int Status = STATUS_SUCCESS;
4424 PUCHAR pcBuff = (PUCHAR)pBuff;
4426 if (uiNumBytes % Adapter->ulFlashWriteSize) {
4427 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
4428 return STATUS_FAILURE;
4431 uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
4433 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
4434 return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
4436 uiOffset = uiOffset + uiStartOffset;
4438 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
4439 Status = bcmflash_raw_writenoerase((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), pcBuff, uiNumBytes);
4441 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4443 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
4445 Adapter->SelectedChip = RESET_CHIP_SELECT;
4446 BcmDoChipSelect(Adapter, uiOffset);
4447 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
4449 for (i = 0; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
4450 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
4451 Status = flashByteWrite(Adapter, uiPartOffset, pcBuff);
4453 Status = flashWrite(Adapter, uiPartOffset, pcBuff);
4455 if (Status != STATUS_SUCCESS)
4458 pcBuff = pcBuff + Adapter->ulFlashWriteSize;
4459 uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize;
4461 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4462 Adapter->SelectedChip = RESET_CHIP_SELECT;
4468 bool IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
4470 bool SectionPresent = false;
4474 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
4475 (IsNonCDLessDevice(Adapter) == false))
4476 SectionPresent = TRUE;
4479 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
4480 (IsNonCDLessDevice(Adapter) == false))
4481 SectionPresent = TRUE;
4484 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
4485 SectionPresent = TRUE;
4488 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
4489 SectionPresent = TRUE;
4492 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
4493 SectionPresent = TRUE;
4496 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
4497 SectionPresent = TRUE;
4500 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
4501 SectionPresent = TRUE;
4504 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
4505 SectionPresent = TRUE;
4508 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
4509 SectionPresent = TRUE;
4511 case CONTROL_SECTION:
4512 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
4513 SectionPresent = TRUE;
4516 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
4517 SectionPresent = false;
4520 return SectionPresent;
4523 static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
4525 int offset = STATUS_FAILURE;
4528 if (IsSectionExistInFlash(Adapter, Section) == false) {
4529 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exist", Section);
4533 offset = BcmGetSectionValStartOffset(Adapter, Section);
4534 if (offset == INVALID_OFFSET) {
4535 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exist", Section);
4539 if (IsSectionExistInVendorInfo(Adapter, Section))
4540 return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
4542 Status = IsOffsetWritable(Adapter, offset);
4546 static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
4548 PUCHAR pBuff = NULL;
4549 unsigned int sig = 0;
4550 unsigned int uiOffset = 0;
4551 unsigned int BlockStatus = 0;
4552 unsigned int uiSectAlignAddr = 0;
4554 Adapter->bSigCorrupted = false;
4555 if (Adapter->bAllDSDWriteAllow == false) {
4556 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
4557 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
4558 return SECTOR_IS_NOT_WRITABLE;
4562 pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL);
4564 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4568 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header);
4569 uiOffset -= MAX_RW_SIZE;
4571 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
4573 sig = *((PUINT)(pBuff + 12));
4575 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
4576 /* Now corrupting the sig by corrupting 4th last Byte. */
4579 if (sig == DSD_IMAGE_MAGIC_NUMBER) {
4580 Adapter->bSigCorrupted = TRUE;
4581 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) {
4582 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4583 BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
4585 WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal,
4586 (uiOffset + 12), BYTE_WRITE_SUPPORT);
4588 BcmRestoreBlockProtectStatus(Adapter, BlockStatus);
4592 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4593 uiOffset, MAX_RW_SIZE);
4596 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
4599 return STATUS_FAILURE;
4603 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
4605 return STATUS_SUCCESS;
4608 static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
4610 PUCHAR pBuff = NULL;
4611 unsigned int sig = 0;
4612 unsigned int uiOffset = 0;
4614 Adapter->bSigCorrupted = false;
4616 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
4617 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
4618 return SECTOR_IS_NOT_WRITABLE;
4621 pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL);
4623 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4629 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
4631 sig = *((PUINT)pBuff);
4634 /* corrupt signature */
4637 if (sig == ISO_IMAGE_MAGIC_NUMBER) {
4638 Adapter->bSigCorrupted = TRUE;
4639 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4640 uiOffset, Adapter->ulFlashWriteSize);
4642 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
4645 return STATUS_FAILURE;
4648 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
4649 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
4652 return STATUS_SUCCESS;
4655 bool IsNonCDLessDevice(struct bcm_mini_adapter *Adapter)
4657 if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)