3 #define DWORD unsigned int
5 static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset);
6 static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter);
7 static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter);
8 static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter);
9 static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter);
10 static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize);
12 static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter);
13 static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter);
14 static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter);
15 static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter);
17 static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
19 static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset);
20 static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section);
21 static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section);
23 static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
24 static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd);
25 static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);
26 static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso);
28 static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
29 static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal);
30 static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiSectAlignAddr);
31 static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff,
32 enum bcm_flash2x_section_val eFlash2xSectionVal,
33 unsigned int uiOffset, unsigned int uiNumBytes);
34 static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter);
35 static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter);
37 static int BeceemFlashBulkRead(
38 struct bcm_mini_adapter *Adapter,
40 unsigned int uiOffset,
41 unsigned int uiNumBytes);
43 static int BeceemFlashBulkWrite(
44 struct bcm_mini_adapter *Adapter,
46 unsigned int uiOffset,
47 unsigned int uiNumBytes,
50 static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter);
52 static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, unsigned int dwAddress, unsigned int *pdwData, unsigned int dwNumData);
54 /* Procedure: ReadEEPROMStatusRegister
56 * Description: Reads the standard EEPROM Status Register.
59 * Adapter - ptr to Adapter object instance
63 static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter)
66 DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
67 unsigned int uiStatus = 0;
68 unsigned int value = 0;
69 unsigned int value1 = 0;
71 /* Read the EEPROM status register */
72 value = EEPROM_READ_STATUS_REGISTER;
73 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
75 while (dwRetries != 0) {
78 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
79 if (Adapter->device_removed == TRUE) {
80 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting....");
84 /* Wait for Avail bit to be set. */
85 if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) {
86 /* Clear the Avail/Full bits - which ever is set. */
87 value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
88 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
91 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
92 uiData = (UCHAR)value;
99 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
100 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
101 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);
104 if (!(dwRetries%RETRIES_PER_DELAY))
109 } /* ReadEEPROMStatusRegister */
112 * Procedure: ReadBeceemEEPROMBulk
114 * Description: This routine reads 16Byte data from EEPROM
117 * Adapter - ptr to Adapter object instance
118 * dwAddress - EEPROM Offset to read the data from.
119 * pdwData - Pointer to double word where data needs to be stored in. // dwNumWords - Number of words. Valid values are 4 ONLY.
125 int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,
131 DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
132 unsigned int uiStatus = 0;
133 unsigned int value = 0;
134 unsigned int value1 = 0;
137 /* Flush the read and cmd queue. */
138 value = (EEPROM_READ_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH);
139 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
141 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
143 /* Clear the Avail/Full bits. */
144 value = (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
145 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
147 value = dwAddress | ((dwNumWords == 4) ? EEPROM_16_BYTE_PAGE_READ : EEPROM_4_BYTE_PAGE_READ);
148 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
150 while (dwRetries != 0) {
152 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
153 if (Adapter->device_removed == TRUE) {
154 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got Removed.hence exiting from loop...");
158 /* If we are reading 16 bytes we want to be sure that the queue
159 * is full before we read. In the other cases we are ok if the
160 * queue has data available
162 if (dwNumWords == 4) {
163 if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) {
164 /* Clear the Avail/Full bits - which ever is set. */
165 value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL));
166 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
169 } else if (dwNumWords == 1) {
170 if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) {
171 /* We just got Avail and we have to read 32bits so we
172 * need this sleep for Cardbus kind of devices.
174 if (Adapter->chip_id == 0xBECE0210)
177 /* Clear the Avail/Full bits - which ever is set. */
178 value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL));
179 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
187 if (dwRetries == 0) {
190 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
191 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
192 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "dwNumWords %d 0x3004 = %x 0x3008 = %x retries = %d failed.\n",
193 dwNumWords, value, value1, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY);
194 return STATUS_FAILURE;
197 if (!(dwRetries%RETRIES_PER_DELAY))
201 for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) {
202 /* We get only a byte at a time - from LSB to MSB. We shift it into an integer. */
203 pvalue = (PUCHAR)(pdwData + dwIndex);
206 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
211 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
216 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
221 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
226 return STATUS_SUCCESS;
227 } /* ReadBeceemEEPROMBulk() */
230 * Procedure: ReadBeceemEEPROM
232 * Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page
233 * reads to do this operation.
236 * Adapter - ptr to Adapter object instance
237 * uiOffset - EEPROM Offset to read the data from.
238 * pBuffer - Pointer to word where data needs to be stored in.
244 int ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter,
248 unsigned int uiData[8] = {0};
249 unsigned int uiByteOffset = 0;
250 unsigned int uiTempOffset = 0;
252 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ====> ");
254 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
255 uiByteOffset = uiOffset - uiTempOffset;
257 ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
259 /* A word can overlap at most over 2 pages. In that case we read the
262 if (uiByteOffset > 12)
263 ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
265 memcpy((PUCHAR)pBuffer, (((PUCHAR)&uiData[0]) + uiByteOffset), 4);
267 return STATUS_SUCCESS;
268 } /* ReadBeceemEEPROM() */
270 int ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter)
273 unsigned char puMacAddr[6];
275 Status = BeceemNVMRead(Adapter,
276 (PUINT)&puMacAddr[0],
277 INIT_PARAMS_1_MACADDRESS_ADDRESS,
280 if (Status == STATUS_SUCCESS)
281 memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
287 * Procedure: BeceemEEPROMBulkRead
289 * Description: Reads the EEPROM and returns the Data.
292 * Adapter - ptr to Adapter object instance
293 * pBuffer - Buffer to store the data read from EEPROM
294 * uiOffset - Offset of EEPROM from where data should be read
295 * uiNumBytes - Number of bytes to be read from the EEPROM.
298 * OSAL_STATUS_SUCCESS - if EEPROM read is successful.
299 * <FAILURE> - if failed.
302 int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter,
304 unsigned int uiOffset,
305 unsigned int uiNumBytes)
307 unsigned int uiData[4] = {0};
308 /* unsigned int uiAddress = 0; */
309 unsigned int uiBytesRemaining = uiNumBytes;
310 unsigned int uiIndex = 0;
311 unsigned int uiTempOffset = 0;
312 unsigned int uiExtraBytes = 0;
313 unsigned int uiFailureRetries = 0;
314 PUCHAR pcBuff = (PUCHAR)pBuffer;
316 if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) {
317 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
318 uiExtraBytes = uiOffset - uiTempOffset;
319 ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
320 if (uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) {
321 memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), MAX_RW_SIZE - uiExtraBytes);
322 uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes);
323 uiIndex += (MAX_RW_SIZE - uiExtraBytes);
324 uiOffset += (MAX_RW_SIZE - uiExtraBytes);
326 memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), uiBytesRemaining);
327 uiIndex += uiBytesRemaining;
328 uiOffset += uiBytesRemaining;
329 uiBytesRemaining = 0;
333 while (uiBytesRemaining && uiFailureRetries != 128) {
334 if (Adapter->device_removed)
337 if (uiBytesRemaining >= MAX_RW_SIZE) {
338 /* For the requests more than or equal to 16 bytes, use bulk
339 * read function to make the access faster.
340 * We read 4 Dwords of data
342 if (ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4) == 0) {
343 memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE);
344 uiOffset += MAX_RW_SIZE;
345 uiBytesRemaining -= MAX_RW_SIZE;
346 uiIndex += MAX_RW_SIZE;
349 mdelay(3); /* sleep for a while before retry... */
351 } else if (uiBytesRemaining >= 4) {
352 if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) {
353 memcpy(pcBuff + uiIndex, &uiData[0], 4);
355 uiBytesRemaining -= 4;
359 mdelay(3); /* sleep for a while before retry... */
362 /* Handle the reads less than 4 bytes... */
363 PUCHAR pCharBuff = (PUCHAR)pBuffer;
364 pCharBuff += uiIndex;
365 if (ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0]) == 0) {
366 memcpy(pCharBuff, &uiData[0], uiBytesRemaining); /* copy only bytes requested. */
367 uiBytesRemaining = 0;
370 mdelay(3); /* sleep for a while before retry... */
379 * Procedure: BeceemFlashBulkRead
381 * Description: Reads the FLASH and returns the Data.
384 * Adapter - ptr to Adapter object instance
385 * pBuffer - Buffer to store the data read from FLASH
386 * uiOffset - Offset of FLASH from where data should be read
387 * uiNumBytes - Number of bytes to be read from the FLASH.
390 * OSAL_STATUS_SUCCESS - if FLASH read is successful.
391 * <FAILURE> - if failed.
394 static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter,
396 unsigned int uiOffset,
397 unsigned int uiNumBytes)
399 unsigned int uiIndex = 0;
400 unsigned int uiBytesToRead = uiNumBytes;
402 unsigned int uiPartOffset = 0;
405 if (Adapter->device_removed) {
406 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed");
410 /* Adding flash Base address
411 * uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
413 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
414 Status = bcmflash_raw_read((uiOffset/FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
418 Adapter->SelectedChip = RESET_CHIP_SELECT;
420 if (uiOffset % MAX_RW_SIZE) {
421 BcmDoChipSelect(Adapter, uiOffset);
422 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
424 uiBytesToRead = MAX_RW_SIZE - (uiOffset % MAX_RW_SIZE);
425 uiBytesToRead = MIN(uiNumBytes, uiBytesToRead);
427 bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
430 Adapter->SelectedChip = RESET_CHIP_SELECT;
434 uiIndex += uiBytesToRead;
435 uiOffset += uiBytesToRead;
436 uiNumBytes -= uiBytesToRead;
440 BcmDoChipSelect(Adapter, uiOffset);
441 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
443 uiBytesToRead = MIN(uiNumBytes, MAX_RW_SIZE);
445 bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
451 uiIndex += uiBytesToRead;
452 uiOffset += uiBytesToRead;
453 uiNumBytes -= uiBytesToRead;
455 Adapter->SelectedChip = RESET_CHIP_SELECT;
460 * Procedure: BcmGetFlashSize
462 * Description: Finds the size of FLASH.
465 * Adapter - ptr to Adapter object instance
468 * unsigned int - size of the FLASH Storage.
472 static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter)
474 if (IsFlash2x(Adapter))
475 return Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header);
481 * Procedure: BcmGetEEPROMSize
483 * Description: Finds the size of EEPROM.
486 * Adapter - ptr to Adapter object instance
489 * unsigned int - size of the EEPROM Storage.
493 static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter)
495 unsigned int uiData = 0;
496 unsigned int uiIndex = 0;
499 * if EEPROM is present and already Calibrated,it will have
500 * 'BECM' string at 0th offset.
501 * To find the EEPROM size read the possible boundaries of the
502 * EEPROM like 4K,8K etc..accessing the EEPROM beyond its size will
503 * result in wrap around. So when we get the End of the EEPROM we will
504 * get 'BECM' string which is indeed at offset 0.
506 BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4);
507 if (uiData == BECM) {
508 for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) {
509 BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4);
511 return uiIndex * 1024;
515 * EEPROM may not be present or not programmed
518 if (BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE) == 0) {
520 for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) {
521 BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4);
522 if (uiData == 0xBABEFACE)
523 return uiIndex * 1024;
531 * Procedure: FlashSectorErase
533 * Description: Finds the sector size of the FLASH.
536 * Adapter - ptr to Adapter object instance
537 * addr - sector start address
538 * numOfSectors - number of sectors to be erased.
545 static int FlashSectorErase(struct bcm_mini_adapter *Adapter,
547 unsigned int numOfSectors)
549 unsigned int iIndex = 0, iRetries = 0;
550 unsigned int uiStatus = 0;
554 for (iIndex = 0; iIndex < numOfSectors; iIndex++) {
556 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
558 value = (0xd8000000 | (addr & 0xFFFFFF));
559 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
563 value = (FLASH_CMD_STATUS_REG_READ << 24);
564 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
565 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
566 return STATUS_FAILURE;
569 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
572 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
576 /* After every try lets make the CPU free for 10 ms. generally time taken by the
577 * the sector erase cycle is 500 ms to 40000 msec. hence sleeping 10 ms
578 * won't hamper performance in any case.
581 } while ((uiStatus & 0x1) && (iRetries < 400));
583 if (uiStatus & 0x1) {
584 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "iRetries crossing the limit of 80000\n");
585 return STATUS_FAILURE;
588 addr += Adapter->uiSectorSize;
593 * Procedure: flashByteWrite
595 * Description: Performs Byte by Byte write to flash
598 * Adapter - ptr to Adapter object instance
599 * uiOffset - Offset of the flash where data needs to be written to.
600 * pData - Address of Data to be written.
606 static int flashByteWrite(struct bcm_mini_adapter *Adapter,
607 unsigned int uiOffset,
610 unsigned int uiStatus = 0;
611 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
613 ULONG ulData = *(PUCHAR)pData;
616 * need not write 0xFF because write requires an erase and erase will
617 * make whole sector 0xFF.
621 return STATUS_SUCCESS;
623 /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */
624 value = (FLASH_CMD_WRITE_ENABLE << 24);
625 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
626 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails");
627 return STATUS_FAILURE;
630 if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) {
631 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails");
632 return STATUS_FAILURE;
634 value = (0x02000000 | (uiOffset & 0xFFFFFF));
635 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
636 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails");
637 return STATUS_FAILURE;
643 value = (FLASH_CMD_STATUS_REG_READ << 24);
644 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
645 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
646 return STATUS_FAILURE;
649 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
652 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
656 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
659 } while ((uiStatus & 0x1) && (iRetries > 0));
661 if (uiStatus & 0x1) {
662 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
663 return STATUS_FAILURE;
666 return STATUS_SUCCESS;
670 * Procedure: flashWrite
672 * Description: Performs write to flash
675 * Adapter - ptr to Adapter object instance
676 * uiOffset - Offset of the flash where data needs to be written to.
677 * pData - Address of Data to be written.
683 static int flashWrite(struct bcm_mini_adapter *Adapter,
684 unsigned int uiOffset,
687 /* unsigned int uiStatus = 0;
689 * unsigned int uiReadBack = 0;
691 unsigned int uiStatus = 0;
692 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
694 unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
697 * need not write 0xFFFFFFFF because write requires an erase and erase will
698 * make whole sector 0xFFFFFFFF.
700 if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
703 value = (FLASH_CMD_WRITE_ENABLE << 24);
705 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
706 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails");
707 return STATUS_FAILURE;
710 if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) {
711 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails...");
712 return STATUS_FAILURE;
717 value = (FLASH_CMD_STATUS_REG_READ << 24);
718 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
719 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
720 return STATUS_FAILURE;
723 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
726 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
731 /* this will ensure that in there will be no changes in the current path.
732 * currently one rdm/wrm takes 125 us.
733 * Hence 125 *2 * FLASH_PER_RETRIES_DELAY > 3 ms(worst case delay)
734 * Hence current implementation cycle will intoduce no delay in current path
736 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
738 } while ((uiStatus & 0x1) && (iRetries > 0));
740 if (uiStatus & 0x1) {
741 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
742 return STATUS_FAILURE;
745 return STATUS_SUCCESS;
748 /*-----------------------------------------------------------------------------
749 * Procedure: flashByteWriteStatus
751 * Description: Performs byte by byte write to flash with write done status check
754 * Adapter - ptr to Adapter object instance
755 * uiOffset - Offset of the flash where data needs to be written to.
756 * pData - Address of the Data to be written.
761 static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter,
762 unsigned int uiOffset,
765 unsigned int uiStatus = 0;
766 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
767 ULONG ulData = *(PUCHAR)pData;
772 * need not write 0xFFFFFFFF because write requires an erase and erase will
773 * make whole sector 0xFFFFFFFF.
777 return STATUS_SUCCESS;
779 /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */
781 value = (FLASH_CMD_WRITE_ENABLE << 24);
782 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
783 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails");
784 return STATUS_SUCCESS;
786 if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) {
787 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails");
788 return STATUS_FAILURE;
790 value = (0x02000000 | (uiOffset & 0xFFFFFF));
791 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
792 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails");
793 return STATUS_FAILURE;
799 value = (FLASH_CMD_STATUS_REG_READ << 24);
800 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
801 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
802 return STATUS_FAILURE;
805 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
808 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
813 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
816 } while ((uiStatus & 0x1) && (iRetries > 0));
818 if (uiStatus & 0x1) {
819 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
820 return STATUS_FAILURE;
823 return STATUS_SUCCESS;
826 * Procedure: flashWriteStatus
828 * Description: Performs write to flash with write done status check
831 * Adapter - ptr to Adapter object instance
832 * uiOffset - Offset of the flash where data needs to be written to.
833 * pData - Address of the Data to be written.
839 static int flashWriteStatus(struct bcm_mini_adapter *Adapter,
840 unsigned int uiOffset,
843 unsigned int uiStatus = 0;
844 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
845 /* unsigned int uiReadBack = 0; */
847 unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
851 * need not write 0xFFFFFFFF because write requires an erase and erase will
852 * make whole sector 0xFFFFFFFF.
854 if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
857 value = (FLASH_CMD_WRITE_ENABLE << 24);
858 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
859 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails");
860 return STATUS_FAILURE;
863 if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) {
864 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails...");
865 return STATUS_FAILURE;
870 value = (FLASH_CMD_STATUS_REG_READ << 24);
871 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
872 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
873 return STATUS_FAILURE;
876 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
879 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
883 /* this will ensure that in there will be no changes in the current path.
884 * currently one rdm/wrm takes 125 us.
885 * Hence 125 *2 * FLASH_PER_RETRIES_DELAY >3 ms(worst case delay)
886 * Hence current implementation cycle will intoduce no delay in current path
888 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
891 } while ((uiStatus & 0x1) && (iRetries > 0));
893 if (uiStatus & 0x1) {
894 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
895 return STATUS_FAILURE;
898 return STATUS_SUCCESS;
902 * Procedure: BcmRestoreBlockProtectStatus
904 * Description: Restores the original block protection status.
907 * Adapter - ptr to Adapter object instance
908 * ulWriteStatus -Original status
914 static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus)
917 value = (FLASH_CMD_WRITE_ENABLE << 24);
918 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
921 value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
922 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
927 * Procedure: BcmFlashUnProtectBlock
929 * Description: UnProtects appropriate blocks for writing.
932 * Adapter - ptr to Adapter object instance
933 * uiOffset - Offset of the flash where data needs to be written to. This should be Sector aligned.
935 * ULONG - Status value before UnProtect.
939 static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned int uiOffset, unsigned int uiLength)
942 ULONG ulWriteStatus = 0;
945 uiOffset = uiOffset&0x000FFFFF;
947 * Implemented only for 1MB Flash parts.
949 if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) {
951 * Get Current BP status.
953 value = (FLASH_CMD_STATUS_REG_READ << 24);
954 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
957 * Read status will be WWXXYYZZ. We have to take only WW.
959 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
961 ulWriteStatus = ulStatus;
963 * Bits [5-2] give current block level protection status.
964 * Bit5: BP3 - DONT CARE
965 * BP2-BP0: 0 - NO PROTECTION, 1 - UPPER 1/16, 2 - UPPER 1/8, 3 - UPPER 1/4
966 * 4 - UPPER 1/2. 5 to 7 - ALL BLOCKS
970 if ((uiOffset+uiLength) <= 0x80000) {
972 * Offset comes in lower half of 1MB. Protect the upper half.
973 * Clear BP1 and BP0 and set BP2.
975 ulWriteStatus |= (0x4<<2);
976 ulWriteStatus &= ~(0x3<<2);
977 } else if ((uiOffset + uiLength) <= 0xC0000) {
979 * Offset comes below Upper 1/4. Upper 1/4 can be protected.
980 * Clear BP2 and set BP1 and BP0.
982 ulWriteStatus |= (0x3<<2);
983 ulWriteStatus &= ~(0x1<<4);
984 } else if ((uiOffset + uiLength) <= 0xE0000) {
986 * Offset comes below Upper 1/8. Upper 1/8 can be protected.
987 * Clear BP2 and BP0 and set BP1
989 ulWriteStatus |= (0x1<<3);
990 ulWriteStatus &= ~(0x5<<2);
991 } else if ((uiOffset + uiLength) <= 0xF0000) {
993 * Offset comes below Upper 1/16. Only upper 1/16 can be protected.
994 * Set BP0 and Clear BP2,BP1.
996 ulWriteStatus |= (0x1<<2);
997 ulWriteStatus &= ~(0x3<<3);
1001 * Clear BP2,BP1 and BP0.
1003 ulWriteStatus &= ~(0x7<<2);
1006 value = (FLASH_CMD_WRITE_ENABLE << 24);
1007 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1009 value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
1010 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1018 * Procedure: BeceemFlashBulkWrite
1020 * Description: Performs write to the flash
1023 * Adapter - ptr to Adapter object instance
1024 * pBuffer - Data to be written.
1025 * uiOffset - Offset of the flash where data needs to be written to.
1026 * uiNumBytes - Number of bytes to be written.
1027 * bVerify - read verify flag.
1033 static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter,
1035 unsigned int uiOffset,
1036 unsigned int uiNumBytes,
1039 PCHAR pTempBuff = NULL;
1040 PUCHAR pcBuffer = (PUCHAR)pBuffer;
1041 unsigned int uiIndex = 0;
1042 unsigned int uiOffsetFromSectStart = 0;
1043 unsigned int uiSectAlignAddr = 0;
1044 unsigned int uiCurrSectOffsetAddr = 0;
1045 unsigned int uiSectBoundary = 0;
1046 unsigned int uiNumSectTobeRead = 0;
1047 UCHAR ucReadBk[16] = {0};
1049 int Status = STATUS_SUCCESS;
1050 unsigned int uiTemp = 0;
1051 unsigned int index = 0;
1052 unsigned int uiPartOffset = 0;
1054 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1055 Status = bcmflash_raw_write((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
1059 uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
1061 /* Adding flash Base address
1062 * uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
1065 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
1066 uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
1067 uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
1069 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
1071 goto BeceemFlashBulkWrite_EXIT;
1073 * check if the data to be written is overlapped across sectors
1075 if (uiOffset+uiNumBytes < uiSectBoundary) {
1076 uiNumSectTobeRead = 1;
1078 /* Number of sectors = Last sector start address/First sector start address */
1079 uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize;
1080 if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize)
1081 uiNumSectTobeRead++;
1083 /* Check whether Requested sector is writable or not in case of flash2x write. But if write call is
1084 * for DSD calibration, allow it without checking of sector permission
1087 if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) {
1089 uiTemp = uiNumSectTobeRead;
1091 if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) {
1092 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%X> is not writable",
1093 (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
1094 Status = SECTOR_IS_NOT_WRITABLE;
1095 goto BeceemFlashBulkWrite_EXIT;
1097 uiTemp = uiTemp - 1;
1101 Adapter->SelectedChip = RESET_CHIP_SELECT;
1102 while (uiNumSectTobeRead) {
1103 /* do_gettimeofday(&tv1);
1104 * 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));
1106 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1108 BcmDoChipSelect(Adapter, uiSectAlignAddr);
1110 if (0 != BeceemFlashBulkRead(Adapter,
1112 uiOffsetFromSectStart,
1113 Adapter->uiSectorSize)) {
1115 goto BeceemFlashBulkWrite_EXIT;
1118 /* do_gettimeofday(&tr);
1119 * 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));
1121 ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
1123 if (uiNumSectTobeRead > 1) {
1124 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1125 pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)));
1126 uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1128 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes);
1131 if (IsFlash2x(Adapter))
1132 SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart);
1134 FlashSectorErase(Adapter, uiPartOffset, 1);
1135 /* do_gettimeofday(&te);
1136 * 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));
1138 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) {
1139 if (Adapter->device_removed) {
1141 goto BeceemFlashBulkWrite_EXIT;
1144 if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) {
1146 goto BeceemFlashBulkWrite_EXIT;
1150 /* do_gettimeofday(&tw);
1151 * 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));
1153 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) {
1154 if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) {
1155 if (Adapter->ulFlashWriteSize == 1) {
1156 unsigned int uiReadIndex = 0;
1157 for (uiReadIndex = 0; uiReadIndex < 16; uiReadIndex++) {
1158 if (ucReadBk[uiReadIndex] != pTempBuff[uiIndex + uiReadIndex]) {
1159 if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex + uiReadIndex, &pTempBuff[uiIndex+uiReadIndex])) {
1160 Status = STATUS_FAILURE;
1161 goto BeceemFlashBulkWrite_EXIT;
1166 if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) {
1167 if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex, &pTempBuff[uiIndex])) {
1168 Status = STATUS_FAILURE;
1169 goto BeceemFlashBulkWrite_EXIT;
1175 /* do_gettimeofday(&twv);
1176 * 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));
1179 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1183 uiCurrSectOffsetAddr = 0;
1184 uiSectAlignAddr = uiSectBoundary;
1185 uiSectBoundary += Adapter->uiSectorSize;
1186 uiOffsetFromSectStart += Adapter->uiSectorSize;
1187 uiNumSectTobeRead--;
1189 /* do_gettimeofday(&tv2);
1190 * BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Time after Write :%ld ms\n",(tv2.tv_sec *1000 + tv2.tv_usec/1000));
1191 * 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));
1195 BeceemFlashBulkWrite_EXIT:
1197 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1201 Adapter->SelectedChip = RESET_CHIP_SELECT;
1206 * Procedure: BeceemFlashBulkWriteStatus
1208 * Description: Writes to Flash. Checks the SPI status after each write.
1211 * Adapter - ptr to Adapter object instance
1212 * pBuffer - Data to be written.
1213 * uiOffset - Offset of the flash where data needs to be written to.
1214 * uiNumBytes - Number of bytes to be written.
1215 * bVerify - read verify flag.
1221 static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter,
1223 unsigned int uiOffset,
1224 unsigned int uiNumBytes,
1227 PCHAR pTempBuff = NULL;
1228 PUCHAR pcBuffer = (PUCHAR)pBuffer;
1229 unsigned int uiIndex = 0;
1230 unsigned int uiOffsetFromSectStart = 0;
1231 unsigned int uiSectAlignAddr = 0;
1232 unsigned int uiCurrSectOffsetAddr = 0;
1233 unsigned int uiSectBoundary = 0;
1234 unsigned int uiNumSectTobeRead = 0;
1235 UCHAR ucReadBk[16] = {0};
1237 unsigned int Status = STATUS_SUCCESS;
1238 unsigned int uiTemp = 0;
1239 unsigned int index = 0;
1240 unsigned int uiPartOffset = 0;
1242 uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1);
1244 /* uiOffset += Adapter->ulFlashCalStart;
1245 * Adding flash Base address
1246 * uiOffset = uiOffset + GetFlashBaseAddr(Adapter);
1248 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
1249 uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1);
1250 uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize;
1252 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
1254 goto BeceemFlashBulkWriteStatus_EXIT;
1257 * check if the data to be written is overlapped across sectors
1259 if (uiOffset+uiNumBytes < uiSectBoundary) {
1260 uiNumSectTobeRead = 1;
1262 /* Number of sectors = Last sector start address/First sector start address */
1263 uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize;
1264 if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize)
1265 uiNumSectTobeRead++;
1268 if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) {
1270 uiTemp = uiNumSectTobeRead;
1272 if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) {
1273 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%x> is not writable",
1274 (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
1275 Status = SECTOR_IS_NOT_WRITABLE;
1276 goto BeceemFlashBulkWriteStatus_EXIT;
1278 uiTemp = uiTemp - 1;
1283 Adapter->SelectedChip = RESET_CHIP_SELECT;
1284 while (uiNumSectTobeRead) {
1285 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1287 BcmDoChipSelect(Adapter, uiSectAlignAddr);
1288 if (0 != BeceemFlashBulkRead(Adapter,
1290 uiOffsetFromSectStart,
1291 Adapter->uiSectorSize)) {
1293 goto BeceemFlashBulkWriteStatus_EXIT;
1296 ulStatus = BcmFlashUnProtectBlock(Adapter, uiOffsetFromSectStart, Adapter->uiSectorSize);
1298 if (uiNumSectTobeRead > 1) {
1299 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1300 pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)));
1301 uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1303 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes);
1306 if (IsFlash2x(Adapter))
1307 SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart);
1309 FlashSectorErase(Adapter, uiPartOffset, 1);
1311 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) {
1312 if (Adapter->device_removed) {
1314 goto BeceemFlashBulkWriteStatus_EXIT;
1317 if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) {
1319 goto BeceemFlashBulkWriteStatus_EXIT;
1324 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += MAX_RW_SIZE) {
1325 if (STATUS_SUCCESS == BeceemFlashBulkRead(Adapter, (PUINT)ucReadBk, uiOffsetFromSectStart + uiIndex, MAX_RW_SIZE)) {
1326 if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) {
1327 Status = STATUS_FAILURE;
1328 goto BeceemFlashBulkWriteStatus_EXIT;
1335 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1339 uiCurrSectOffsetAddr = 0;
1340 uiSectAlignAddr = uiSectBoundary;
1341 uiSectBoundary += Adapter->uiSectorSize;
1342 uiOffsetFromSectStart += Adapter->uiSectorSize;
1343 uiNumSectTobeRead--;
1348 BeceemFlashBulkWriteStatus_EXIT:
1350 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1353 Adapter->SelectedChip = RESET_CHIP_SELECT;
1358 * Procedure: PropagateCalParamsFromEEPROMToMemory
1360 * Description: Dumps the calibration section of EEPROM to DDR.
1363 * Adapter - ptr to Adapter object instance
1369 int PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter)
1371 PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL);
1372 unsigned int uiEepromSize = 0;
1373 unsigned int uiIndex = 0;
1374 unsigned int uiBytesToCopy = 0;
1375 unsigned int uiCalStartAddr = EEPROM_CALPARAM_START;
1376 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1383 if (0 != BeceemEEPROMBulkRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) {
1388 uiEepromSize >>= 16;
1389 if (uiEepromSize > 1024 * 1024) {
1394 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
1396 while (uiBytesToCopy) {
1397 if (0 != BeceemEEPROMBulkRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiBytesToCopy)) {
1401 wrm(Adapter, uiMemoryLoc, (PCHAR)(((PULONG)pBuff) + uiIndex), uiBytesToCopy);
1402 uiMemoryLoc += uiBytesToCopy;
1403 uiEepromSize -= uiBytesToCopy;
1404 uiCalStartAddr += uiBytesToCopy;
1405 uiIndex += uiBytesToCopy / 4;
1406 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
1410 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
1412 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
1419 * Procedure: PropagateCalParamsFromFlashToMemory
1421 * Description: Dumps the calibration section of EEPROM to DDR.
1424 * Adapter - ptr to Adapter object instance
1430 int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter)
1433 unsigned int uiEepromSize = 0;
1434 unsigned int uiBytesToCopy = 0;
1435 /* unsigned int uiIndex = 0; */
1436 unsigned int uiCalStartAddr = EEPROM_CALPARAM_START;
1437 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1442 * Write the signature first. This will ensure firmware does not access EEPROM.
1445 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
1447 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
1449 if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4))
1452 uiEepromSize = ntohl(uiEepromSize);
1453 uiEepromSize >>= 16;
1456 * subtract the auto init section size
1458 uiEepromSize -= EEPROM_CALPARAM_START;
1460 if (uiEepromSize > 1024 * 1024)
1463 pBuff = kmalloc(uiEepromSize, GFP_KERNEL);
1467 if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) {
1474 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
1476 while (uiBytesToCopy) {
1477 Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy);
1479 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status);
1483 pPtr += uiBytesToCopy;
1484 uiEepromSize -= uiBytesToCopy;
1485 uiMemoryLoc += uiBytesToCopy;
1486 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
1494 * Procedure: BeceemEEPROMReadBackandVerify
1496 * Description: Read back the data written and verifies.
1499 * Adapter - ptr to Adapter object instance
1500 * pBuffer - Data to be written.
1501 * uiOffset - Offset of the flash where data needs to be written to.
1502 * uiNumBytes - Number of bytes to be written.
1508 static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter,
1510 unsigned int uiOffset,
1511 unsigned int uiNumBytes)
1513 unsigned int uiRdbk = 0;
1514 unsigned int uiIndex = 0;
1515 unsigned int uiData = 0;
1516 unsigned int auiData[4] = {0};
1518 while (uiNumBytes) {
1519 if (Adapter->device_removed)
1522 if (uiNumBytes >= MAX_RW_SIZE) {
1523 /* for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. */
1524 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
1526 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) {
1528 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, FALSE);
1530 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
1532 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE))
1535 uiOffset += MAX_RW_SIZE;
1536 uiNumBytes -= MAX_RW_SIZE;
1538 } else if (uiNumBytes >= 4) {
1539 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
1540 if (uiData != pBuffer[uiIndex]) {
1542 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, FALSE);
1544 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
1545 if (uiData != pBuffer[uiIndex])
1552 /* Handle the reads less than 4 bytes... */
1554 memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(unsigned int)), uiNumBytes);
1555 BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4);
1557 if (memcmp(&uiData, &uiRdbk, uiNumBytes))
1567 static VOID BcmSwapWord(unsigned int *ptr1)
1569 unsigned int tempval = (unsigned int)*ptr1;
1570 char *ptr2 = (char *)&tempval;
1571 char *ptr = (char *)ptr1;
1580 * Procedure: BeceemEEPROMWritePage
1582 * Description: Performs page write (16bytes) to the EEPROM
1585 * Adapter - ptr to Adapter object instance
1586 * uiData - Data to be written.
1587 * uiOffset - Offset of the EEPROM where data needs to be written to.
1593 static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, unsigned int uiData[], unsigned int uiOffset)
1595 unsigned int uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
1596 unsigned int uiStatus = 0;
1597 UCHAR uiEpromStatus = 0;
1598 unsigned int value = 0;
1600 /* Flush the Write/Read/Cmd queues. */
1601 value = (EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH);
1602 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
1604 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
1606 /* Clear the Empty/Avail/Full bits. After this it has been confirmed
1607 * that the bit was cleared by reading back the register. See NOTE below.
1608 * We also clear the Read queues as we do a EEPROM status register read
1611 value = (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
1612 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
1615 value = EEPROM_WRITE_ENABLE;
1616 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
1618 /* We can write back to back 8bits * 16 into the queue and as we have
1619 * checked for the queue to be empty we can write in a burst.
1623 BcmSwapWord(&value);
1624 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1627 BcmSwapWord(&value);
1628 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1631 BcmSwapWord(&value);
1632 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1635 BcmSwapWord(&value);
1636 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1638 /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG
1639 * shows that we see 7 for the EEPROM data write. Which means that
1640 * queue got full, also space is available as well as the queue is empty.
1641 * This may happen in sequence.
1643 value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset;
1644 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
1646 /* Ideally we should loop here without tries and eventually succeed.
1647 * What we are checking if the previous write has completed, and this
1648 * may take time. We should wait till the Empty bit is set.
1651 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
1652 while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) {
1654 if (uiRetries == 0) {
1655 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY);
1656 return STATUS_FAILURE;
1659 if (!(uiRetries%RETRIES_PER_DELAY))
1663 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
1664 if (Adapter->device_removed == TRUE) {
1665 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop....");
1670 if (uiRetries != 0) {
1671 /* Clear the ones that are set - either, Empty/Full/Avail bits */
1672 value = (uiStatus & (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL));
1673 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
1676 /* Here we should check if the EEPROM status register is correct before
1677 * proceeding. Bit 0 in the EEPROM Status register should be 0 before
1678 * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy
1679 * with the previous write. Note also that issuing this read finally
1680 * means the previous write to the EEPROM has completed.
1682 uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
1684 while (uiRetries != 0) {
1685 uiEpromStatus = ReadEEPROMStatusRegister(Adapter);
1686 if (Adapter->device_removed == TRUE) {
1687 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
1690 if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) {
1691 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY - uiRetries));
1692 return STATUS_SUCCESS;
1695 if (uiRetries == 0) {
1696 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);
1697 return STATUS_FAILURE;
1700 if (!(uiRetries%RETRIES_PER_DELAY))
1704 return STATUS_SUCCESS;
1705 } /* BeceemEEPROMWritePage */
1708 * Procedure: BeceemEEPROMBulkWrite
1710 * Description: Performs write to the EEPROM
1713 * Adapter - ptr to Adapter object instance
1714 * pBuffer - Data to be written.
1715 * uiOffset - Offset of the EEPROM where data needs to be written to.
1716 * uiNumBytes - Number of bytes to be written.
1717 * bVerify - read verify flag.
1723 int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter,
1725 unsigned int uiOffset,
1726 unsigned int uiNumBytes,
1729 unsigned int uiBytesToCopy = uiNumBytes;
1730 /* unsigned int uiRdbk = 0; */
1731 unsigned int uiData[4] = {0};
1732 unsigned int uiIndex = 0;
1733 unsigned int uiTempOffset = 0;
1734 unsigned int uiExtraBytes = 0;
1735 /* PUINT puiBuffer = (PUINT)pBuffer;
1739 if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) {
1740 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
1741 uiExtraBytes = uiOffset - uiTempOffset;
1743 BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE);
1745 if (uiBytesToCopy >= (16 - uiExtraBytes)) {
1746 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes);
1748 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
1749 return STATUS_FAILURE;
1751 uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes);
1752 uiIndex += (MAX_RW_SIZE - uiExtraBytes);
1753 uiOffset += (MAX_RW_SIZE - uiExtraBytes);
1755 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy);
1757 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
1758 return STATUS_FAILURE;
1760 uiIndex += uiBytesToCopy;
1761 uiOffset += uiBytesToCopy;
1766 while (uiBytesToCopy) {
1767 if (Adapter->device_removed)
1770 if (uiBytesToCopy >= MAX_RW_SIZE) {
1771 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset))
1772 return STATUS_FAILURE;
1774 uiIndex += MAX_RW_SIZE;
1775 uiOffset += MAX_RW_SIZE;
1776 uiBytesToCopy -= MAX_RW_SIZE;
1779 * To program non 16byte aligned data, read 16byte and then update.
1781 BeceemEEPROMBulkRead(Adapter, &uiData[0], uiOffset, 16);
1782 memcpy(&uiData[0], pBuffer + uiIndex, uiBytesToCopy);
1784 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiOffset))
1785 return STATUS_FAILURE;
1795 * Procedure: BeceemNVMRead
1797 * Description: Reads n number of bytes from NVM.
1800 * Adapter - ptr to Adapter object instance
1801 * pBuffer - Buffer to store the data read from NVM
1802 * uiOffset - Offset of NVM from where data should be read
1803 * uiNumBytes - Number of bytes to be read from the NVM.
1806 * OSAL_STATUS_SUCCESS - if NVM read is successful.
1807 * <FAILURE> - if failed.
1810 int BeceemNVMRead(struct bcm_mini_adapter *Adapter,
1812 unsigned int uiOffset,
1813 unsigned int uiNumBytes)
1817 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
1818 unsigned int uiTemp = 0, value;
1821 if (Adapter->eNVMType == NVM_FLASH) {
1822 if (Adapter->bFlashRawRead == FALSE) {
1823 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
1824 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes);
1826 uiOffset = uiOffset + Adapter->ulFlashCalStart;
1829 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1830 Status = bcmflash_raw_read((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
1832 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1834 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
1835 Status = BeceemFlashBulkRead(Adapter,
1839 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1841 } else if (Adapter->eNVMType == NVM_EEPROM) {
1842 Status = BeceemEEPROMBulkRead(Adapter,
1854 * Procedure: BeceemNVMWrite
1856 * Description: Writes n number of bytes to NVM.
1859 * Adapter - ptr to Adapter object instance
1860 * pBuffer - Buffer contains the data to be written.
1861 * uiOffset - Offset of NVM where data to be written to.
1862 * uiNumBytes - Number of bytes to be written..
1865 * OSAL_STATUS_SUCCESS - if NVM write is successful.
1866 * <FAILURE> - if failed.
1869 int BeceemNVMWrite(struct bcm_mini_adapter *Adapter,
1871 unsigned int uiOffset,
1872 unsigned int uiNumBytes,
1876 unsigned int uiTemp = 0;
1877 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1878 unsigned int uiIndex = 0;
1880 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
1884 unsigned int uiFlashOffset = 0;
1886 if (Adapter->eNVMType == NVM_FLASH) {
1887 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
1888 Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify);
1890 uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;
1892 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1893 Status = bcmflash_raw_write((uiFlashOffset / FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
1895 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1897 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
1899 if (Adapter->bStatusWrite == TRUE)
1900 Status = BeceemFlashBulkWriteStatus(Adapter,
1907 Status = BeceemFlashBulkWrite(Adapter,
1915 if (uiOffset >= EEPROM_CALPARAM_START) {
1916 uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
1917 while (uiNumBytes) {
1918 if (uiNumBytes > BUFFER_4K) {
1919 wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K);
1920 uiNumBytes -= BUFFER_4K;
1921 uiIndex += BUFFER_4K;
1923 wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes);
1929 if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) {
1930 ULONG ulBytesTobeSkipped = 0;
1931 PUCHAR pcBuffer = (PUCHAR)pBuffer; /* char pointer to take care of odd byte cases. */
1932 uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
1933 ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
1934 uiOffset += (EEPROM_CALPARAM_START - uiOffset);
1935 while (uiNumBytes) {
1936 if (uiNumBytes > BUFFER_4K) {
1937 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K);
1938 uiNumBytes -= BUFFER_4K;
1939 uiIndex += BUFFER_4K;
1941 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes);
1948 /* restore the values. */
1949 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1950 } else if (Adapter->eNVMType == NVM_EEPROM) {
1951 Status = BeceemEEPROMBulkWrite(Adapter,
1957 Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes);
1965 * Procedure: BcmUpdateSectorSize
1967 * Description: Updates the sector size to FLASH.
1970 * Adapter - ptr to Adapter object instance
1971 * uiSectorSize - sector size
1974 * OSAL_STATUS_SUCCESS - if NVM write is successful.
1975 * <FAILURE> - if failed.
1978 int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, unsigned int uiSectorSize)
1981 struct bcm_flash_cs_info sFlashCsInfo = {0};
1982 unsigned int uiTemp = 0;
1983 unsigned int uiSectorSig = 0;
1984 unsigned int uiCurrentSectorSize = 0;
1987 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1989 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
1992 * Before updating the sector size in the reserved area, check if already present.
1994 BeceemFlashBulkRead(Adapter, (PUINT)&sFlashCsInfo, Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo));
1995 uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
1996 uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);
1998 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
1999 if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) {
2000 if (uiSectorSize == uiCurrentSectorSize) {
2001 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash");
2002 Status = STATUS_SUCCESS;
2008 if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) {
2009 sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize);
2010 sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG);
2012 Status = BeceemFlashBulkWrite(Adapter,
2013 (PUINT)&sFlashCsInfo,
2014 Adapter->ulFlashControlSectionStart,
2015 sizeof(sFlashCsInfo),
2020 /* restore the values. */
2021 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2027 * Procedure: BcmGetFlashSectorSize
2029 * Description: Finds the sector size of the FLASH.
2032 * Adapter - ptr to Adapter object instance
2035 * unsigned int - sector size.
2039 static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize)
2041 unsigned int uiSectorSize = 0;
2042 unsigned int uiSectorSig = 0;
2044 if (Adapter->bSectorSizeOverride &&
2045 (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2046 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) {
2047 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2049 uiSectorSig = FlashSectorSizeSig;
2051 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
2052 uiSectorSize = FlashSectorSize;
2054 * If the sector size stored in the FLASH makes sense then use it.
2056 if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) {
2057 Adapter->uiSectorSize = uiSectorSize;
2058 } else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2059 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) {
2060 /* No valid size in FLASH, check if Config file has it. */
2061 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2063 /* Init to Default, if none of the above works. */
2064 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2067 if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2068 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
2069 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2071 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2075 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x\n", Adapter->uiSectorSize);
2077 return Adapter->uiSectorSize;
2081 * Procedure: BcmInitEEPROMQueues
2083 * Description: Initialization of EEPROM queues.
2086 * Adapter - ptr to Adapter object instance
2089 * <OSAL_STATUS_CODE>
2092 static int BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter)
2094 unsigned int value = 0;
2095 /* CHIP Bug : Clear the Avail bits on the Read queue. The default
2096 * value on this register is supposed to be 0x00001102.
2097 * But we get 0x00001122.
2099 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n");
2100 value = EEPROM_READ_DATA_AVAIL;
2101 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
2103 /* Flush the all the EEPROM queues. */
2104 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n");
2105 value = EEPROM_ALL_QUEUE_FLUSH;
2106 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
2109 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
2111 /* Read the EEPROM Status Register. Just to see, no real purpose. */
2112 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter));
2114 return STATUS_SUCCESS;
2115 } /* BcmInitEEPROMQueues() */
2118 * Procedure: BcmInitNVM
2120 * Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc.
2123 * Adapter - ptr to Adapter object instance
2126 * <OSAL_STATUS_CODE>
2129 int BcmInitNVM(struct bcm_mini_adapter *ps_adapter)
2131 BcmValidateNvmType(ps_adapter);
2132 BcmInitEEPROMQueues(ps_adapter);
2134 if (ps_adapter->eNVMType == NVM_AUTODETECT) {
2135 ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
2136 if (ps_adapter->eNVMType == NVM_UNKNOWN)
2137 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
2138 } else if (ps_adapter->eNVMType == NVM_FLASH) {
2139 BcmGetFlashCSInfo(ps_adapter);
2142 BcmGetNvmSize(ps_adapter);
2144 return STATUS_SUCCESS;
2147 /* BcmGetNvmSize : set the EEPROM or flash size in Adapter.
2150 * Adapter data structure
2155 static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter)
2157 if (Adapter->eNVMType == NVM_EEPROM)
2158 Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
2159 else if (Adapter->eNVMType == NVM_FLASH)
2160 Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
2166 * Procedure: BcmValidateNvm
2168 * Description: Validates the NVM Type option selected against the device
2171 * Adapter - ptr to Adapter object instance
2177 static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter)
2180 * if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
2181 * Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
2182 * So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
2185 if (Adapter->eNVMType == NVM_FLASH &&
2186 Adapter->chip_id < 0xBECE3300)
2187 Adapter->eNVMType = NVM_AUTODETECT;
2191 * Procedure: BcmReadFlashRDID
2193 * Description: Reads ID from Serial Flash
2196 * Adapter - ptr to Adapter object instance
2202 static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter)
2208 * Read ID Instruction.
2210 value = (FLASH_CMD_READ_ID << 24);
2211 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
2217 * Read SPI READQ REG. The output will be WWXXYYZZ.
2218 * The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
2220 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID));
2225 int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
2228 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
2231 psAdapter->psFlashCSInfo = kzalloc(sizeof(struct bcm_flash_cs_info), GFP_KERNEL);
2232 if (psAdapter->psFlashCSInfo == NULL) {
2233 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x");
2237 psAdapter->psFlash2xCSInfo = kzalloc(sizeof(struct bcm_flash2x_cs_info), GFP_KERNEL);
2238 if (!psAdapter->psFlash2xCSInfo) {
2239 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x");
2240 kfree(psAdapter->psFlashCSInfo);
2244 psAdapter->psFlash2xVendorInfo = kzalloc(sizeof(struct bcm_flash2x_vendor_info), GFP_KERNEL);
2245 if (!psAdapter->psFlash2xVendorInfo) {
2246 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x");
2247 kfree(psAdapter->psFlashCSInfo);
2248 kfree(psAdapter->psFlash2xCSInfo);
2252 return STATUS_SUCCESS;
2255 int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
2258 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
2261 kfree(psAdapter->psFlashCSInfo);
2262 kfree(psAdapter->psFlash2xCSInfo);
2263 kfree(psAdapter->psFlash2xVendorInfo);
2264 return STATUS_SUCCESS;
2267 static int BcmDumpFlash2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo, struct bcm_mini_adapter *Adapter)
2269 unsigned int Index = 0;
2271 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
2272 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber));
2273 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2274 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2275 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
2276 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
2277 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
2278 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
2279 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware));
2280 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
2281 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
2282 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
2283 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
2284 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
2285 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
2286 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
2287 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
2288 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
2289 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
2290 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
2291 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
2292 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
2293 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
2294 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
2295 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
2296 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
2297 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
2298 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
2299 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
2300 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
2301 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
2302 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
2303 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
2304 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
2305 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
2306 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
2307 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
2308 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
2309 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
2310 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
2311 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
2312 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
2313 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
2314 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
2315 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
2316 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
2317 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
2318 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
2320 for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++)
2321 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
2322 (psFlash2xCSInfo->SectorAccessBitMap[Index]));
2324 return STATUS_SUCCESS;
2327 static int ConvertEndianOf2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo)
2329 unsigned int Index = 0;
2331 psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
2332 psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion);
2333 /* psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); */
2334 psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
2335 psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
2336 psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
2337 psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
2338 psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware);
2339 psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
2340 psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
2341 psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
2342 psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
2343 psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
2344 psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
2345 psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
2346 psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
2347 psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
2348 psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
2349 psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
2350 psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
2351 psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
2352 psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
2353 psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
2354 psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
2355 psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
2356 psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
2357 psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
2358 psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
2359 psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
2360 psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
2361 psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
2362 psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
2363 psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
2364 psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
2365 psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
2366 psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
2367 psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
2368 psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
2369 psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
2370 psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
2371 psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
2372 psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
2373 psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
2374 psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
2375 psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
2376 psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
2378 for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++)
2379 psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
2381 return STATUS_SUCCESS;
2384 static int ConvertEndianOfCSStructure(struct bcm_flash_cs_info *psFlashCSInfo)
2386 /* unsigned int Index = 0; */
2387 psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber);
2388 psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion);
2389 psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion);
2390 /* won't convert according to old assumption */
2391 psFlashCSInfo->SCSIFirmwareVersion = (psFlashCSInfo->SCSIFirmwareVersion);
2392 psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
2393 psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
2394 psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware);
2395 psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
2396 psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2397 psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
2398 psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
2399 psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
2400 psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
2401 psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
2402 psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout);
2403 psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature);
2404 psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig);
2405 psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize);
2406 psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize);
2407 psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize);
2408 psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr);
2409 psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize);
2410 psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
2411 psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout);
2413 return STATUS_SUCCESS;
2416 static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
2418 return (Adapter->uiVendorExtnFlag &&
2419 (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
2420 (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS));
2423 static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter)
2426 unsigned int uiSizeSection = 0;
2428 Adapter->uiVendorExtnFlag = FALSE;
2430 for (i = 0; i < TOTAL_SECTIONS; i++)
2431 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
2433 if (STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
2437 while (i < TOTAL_SECTIONS) {
2438 if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) {
2443 Adapter->uiVendorExtnFlag = TRUE;
2444 uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
2445 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
2449 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
2450 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2451 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
2453 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
2457 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
2458 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2459 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
2461 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
2465 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
2466 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2467 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
2469 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
2472 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2473 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
2475 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
2479 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2480 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
2482 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
2485 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2486 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
2488 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
2499 * Procedure: BcmGetFlashCSInfo
2501 * Description: Reads control structure and gets Cal section addresses.
2504 * Adapter - ptr to Adapter object instance
2510 static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter)
2512 /* struct bcm_flash_cs_info sFlashCsInfo = {0}; */
2514 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2518 unsigned int uiFlashLayoutMajorVersion;
2519 Adapter->uiFlashLayoutMinorVersion = 0;
2520 Adapter->uiFlashLayoutMajorVersion = 0;
2521 Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
2523 Adapter->uiFlashBaseAdd = 0;
2524 Adapter->ulFlashCalStart = 0;
2525 memset(Adapter->psFlashCSInfo, 0 , sizeof(struct bcm_flash_cs_info));
2526 memset(Adapter->psFlash2xCSInfo, 0 , sizeof(struct bcm_flash2x_cs_info));
2528 if (!Adapter->bDDRInitDone) {
2529 value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
2530 wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
2533 /* Reading first 8 Bytes to get the Flash Layout
2534 * MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
2536 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8);
2538 Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
2539 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
2540 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); */
2541 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));
2543 if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) {
2544 uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2545 Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2547 Adapter->uiFlashLayoutMinorVersion = 0;
2548 uiFlashLayoutMajorVersion = 0;
2551 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);
2553 if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) {
2554 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash_cs_info));
2555 ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
2556 Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2558 if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
2559 Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
2561 if ((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) &&
2562 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) &&
2563 (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) &&
2564 (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) {
2565 Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
2566 Adapter->fpFlashWrite = flashByteWrite;
2567 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2569 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2570 Adapter->fpFlashWrite = flashWrite;
2571 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2574 BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
2575 (Adapter->psFlashCSInfo->FlashSectorSize));
2576 Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2578 if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL,
2579 Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash2x_cs_info))) {
2580 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n");
2581 return STATUS_FAILURE;
2584 ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
2585 BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo, Adapter);
2586 if ((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
2587 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
2588 (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
2589 (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) {
2590 Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
2591 Adapter->fpFlashWrite = flashByteWrite;
2592 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2594 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2595 Adapter->fpFlashWrite = flashWrite;
2596 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2599 BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
2600 Adapter->psFlash2xCSInfo->FlashSectorSize);
2602 UpdateVendorInfo(Adapter);
2604 BcmGetActiveDSD(Adapter);
2605 BcmGetActiveISO(Adapter);
2606 Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2607 Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;
2610 * Concerns: what if CS sector size does not match with this sector size ???
2611 * what is the indication of AccessBitMap in CS in flash 2.x ????
2613 Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
2614 Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
2616 return STATUS_SUCCESS;
2620 * Procedure: BcmGetNvmType
2622 * Description: Finds the type of NVM used.
2625 * Adapter - ptr to Adapter object instance
2632 static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter)
2634 unsigned int uiData = 0;
2636 BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4);
2641 * Read control struct and get cal addresses before accessing the flash
2643 BcmGetFlashCSInfo(Adapter);
2645 BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4);
2650 * even if there is no valid signature on EEPROM/FLASH find out if they really exist.
2651 * if exist select it.
2653 if (BcmGetEEPROMSize(Adapter))
2656 /* TBD for Flash. */
2661 * BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
2662 * @Adapter : Drivers Private Data structure
2663 * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
2666 * On success it return the start offset of the provided section val
2667 * On Failure -returns STATUS_FAILURE
2670 int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
2673 * Considering all the section for which end offset can be calculated or directly given
2674 * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
2675 * endoffset can't be calculated or given in CS Structure.
2678 int SectStartOffset = 0;
2680 SectStartOffset = INVALID_OFFSET;
2682 if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal))
2683 return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
2685 switch (eFlashSectionVal) {
2687 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
2688 (IsNonCDLessDevice(Adapter) == FALSE))
2689 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
2692 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
2693 (IsNonCDLessDevice(Adapter) == FALSE))
2694 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
2697 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
2698 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
2701 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
2702 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
2705 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
2706 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
2709 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
2710 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
2713 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
2714 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
2717 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
2718 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
2721 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
2722 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
2724 case CONTROL_SECTION:
2725 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
2726 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
2728 case ISO_IMAGE1_PART2:
2729 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
2730 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
2732 case ISO_IMAGE1_PART3:
2733 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
2734 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
2736 case ISO_IMAGE2_PART2:
2737 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
2738 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
2740 case ISO_IMAGE2_PART3:
2741 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
2742 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
2745 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
2746 SectStartOffset = INVALID_OFFSET;
2749 return SectStartOffset;
2753 * BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
2754 * @Adapter : Drivers Private Data structure
2755 * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
2758 * On success it return the end offset of the provided section val
2759 * On Failure -returns STATUS_FAILURE
2762 int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
2764 int SectEndOffset = 0;
2766 SectEndOffset = INVALID_OFFSET;
2767 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
2768 return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
2770 switch (eFlash2xSectionVal) {
2772 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) &&
2773 (IsNonCDLessDevice(Adapter) == FALSE))
2774 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
2777 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) &&
2778 (IsNonCDLessDevice(Adapter) == FALSE))
2779 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
2782 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
2783 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
2786 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
2787 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
2790 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
2791 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
2794 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
2795 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
2798 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
2799 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
2802 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
2803 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
2806 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
2807 SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
2808 (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
2810 case CONTROL_SECTION:
2811 /* Not Clear So Putting failure. confirm and fix it. */
2812 SectEndOffset = STATUS_FAILURE;
2814 case ISO_IMAGE1_PART2:
2815 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS)
2816 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
2818 case ISO_IMAGE1_PART3:
2819 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS)
2820 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
2822 case ISO_IMAGE2_PART2:
2823 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
2824 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
2826 case ISO_IMAGE2_PART3:
2827 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS)
2828 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
2831 SectEndOffset = INVALID_OFFSET;
2834 return SectEndOffset ;
2838 * BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
2839 * @Adapter :Driver Private Data Structure
2840 * @pBuffer : Buffer where data has to be put after reading
2841 * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
2842 * @uiOffsetWithinSectionVal :- Offset with in provided section
2843 * @uiNumBytes : Number of Bytes for Read
2846 * return true on success and STATUS_FAILURE on fail.
2849 int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
2851 enum bcm_flash2x_section_val eFlash2xSectionVal,
2852 unsigned int uiOffsetWithinSectionVal,
2853 unsigned int uiNumBytes)
2855 int Status = STATUS_SUCCESS;
2856 int SectionStartOffset = 0;
2857 unsigned int uiAbsoluteOffset = 0;
2858 unsigned int uiTemp = 0, value = 0;
2861 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
2864 if (Adapter->device_removed) {
2865 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
2869 /* NO_SECTION_VAL means absolute offset is given. */
2870 if (eFlash2xSectionVal == NO_SECTION_VAL)
2871 SectionStartOffset = 0;
2873 SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
2875 if (SectionStartOffset == STATUS_FAILURE) {
2876 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash 2.x Map ", eFlash2xSectionVal);
2880 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
2881 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
2883 /* calculating the absolute offset from FLASH; */
2884 uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
2885 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2887 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2888 Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes);
2889 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2891 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
2899 * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
2900 * @Adapter :Driver Private Data Structure
2901 * @pBuffer : Buffer From where data has to taken for writing
2902 * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
2903 * @uiOffsetWithinSectionVal :- Offset with in provided section
2904 * @uiNumBytes : Number of Bytes for Write
2907 * return true on success and STATUS_FAILURE on fail.
2911 int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
2913 enum bcm_flash2x_section_val eFlash2xSectVal,
2914 unsigned int uiOffset,
2915 unsigned int uiNumBytes,
2916 unsigned int bVerify)
2918 int Status = STATUS_SUCCESS;
2919 unsigned int FlashSectValStartOffset = 0;
2920 unsigned int uiTemp = 0, value = 0;
2923 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
2927 if (Adapter->device_removed) {
2928 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
2932 /* NO_SECTION_VAL means absolute offset is given. */
2933 if (eFlash2xSectVal == NO_SECTION_VAL)
2934 FlashSectValStartOffset = 0;
2936 FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal);
2938 if (FlashSectValStartOffset == STATUS_FAILURE) {
2939 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash Map 2.x", eFlash2xSectVal);
2943 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal))
2944 return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
2946 /* calculating the absolute offset from FLASH; */
2947 uiOffset = uiOffset + FlashSectValStartOffset;
2949 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2951 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2953 Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify);
2955 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2957 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
2965 * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
2966 * @Adapter :-Drivers private Data Structure
2969 * Return STATUS_SUCESS if get success in setting the right DSD else negative error code
2973 static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter)
2975 enum bcm_flash2x_section_val uiHighestPriDSD = 0;
2977 uiHighestPriDSD = getHighestPriDSD(Adapter);
2978 Adapter->eActiveDSD = uiHighestPriDSD;
2980 if (DSD0 == uiHighestPriDSD)
2981 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
2982 if (DSD1 == uiHighestPriDSD)
2983 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
2984 if (DSD2 == uiHighestPriDSD)
2985 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
2986 if (Adapter->eActiveDSD)
2987 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
2988 if (Adapter->eActiveDSD == 0) {
2989 /* if No DSD gets Active, Make Active the DSD with WR permission */
2990 if (IsSectionWritable(Adapter, DSD2)) {
2991 Adapter->eActiveDSD = DSD2;
2992 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
2993 } else if (IsSectionWritable(Adapter, DSD1)) {
2994 Adapter->eActiveDSD = DSD1;
2995 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
2996 } else if (IsSectionWritable(Adapter, DSD0)) {
2997 Adapter->eActiveDSD = DSD0;
2998 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
3002 return STATUS_SUCCESS;
3006 * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
3007 * @Adapter : Driver private Data Structure
3010 * Sucsess:- STATUS_SUCESS
3011 * Failure- : negative erro code
3015 static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter)
3017 int HighestPriISO = 0;
3019 HighestPriISO = getHighestPriISO(Adapter);
3021 Adapter->eActiveISO = HighestPriISO;
3022 if (Adapter->eActiveISO == ISO_IMAGE2)
3023 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
3024 else if (Adapter->eActiveISO == ISO_IMAGE1)
3025 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3027 if (Adapter->eActiveISO)
3028 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO);
3030 return STATUS_SUCCESS;
3034 * IsOffsetWritable :- it will tell the access permission of the sector having passed offset
3035 * @Adapter : Drivers Private Data Structure
3036 * @uiOffset : Offset provided in the Flash
3039 * Success:-TRUE , offset is writable
3040 * Failure:-FALSE, offset is RO
3044 B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset)
3046 unsigned int uiSectorNum = 0;
3047 unsigned int uiWordOfSectorPermission = 0;
3048 unsigned int uiBitofSectorePermission = 0;
3049 B_UINT32 permissionBits = 0;
3051 uiSectorNum = uiOffset/Adapter->uiSectorSize;
3053 /* calculating the word having this Sector Access permission from SectorAccessBitMap Array */
3054 uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16];
3056 /* calculating the bit index inside the word for this sector */
3057 uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16);
3059 /* Setting Access permission */
3060 permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission);
3061 permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
3062 if (permissionBits == SECTOR_READWRITE_PERMISSION)
3068 static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap)
3070 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
3072 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
3073 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1);
3074 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2);
3075 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD0 :0X%x", psFlash2xBitMap->DSD0);
3076 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD1 :0X%x", psFlash2xBitMap->DSD1);
3077 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD2 :0X%x", psFlash2xBitMap->DSD2);
3078 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA0 :0X%x", psFlash2xBitMap->VSA0);
3079 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA1 :0X%x", psFlash2xBitMap->VSA1);
3080 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA2 :0X%x", psFlash2xBitMap->VSA2);
3081 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSI :0X%x", psFlash2xBitMap->SCSI);
3082 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION);
3084 return STATUS_SUCCESS;
3088 * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
3089 * 8bit has been assigned to every section.
3090 * bit[0] :Section present or not
3091 * bit[1] :section is valid or not
3092 * bit[2] : Secton is read only or has write permission too.
3093 * bit[3] : Active Section -
3094 * bit[7...4] = Reserved .
3096 * @Adapter:-Driver private Data Structure
3099 * Success:- STATUS_SUCESS
3100 * Failure:- negative error code
3103 int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap)
3105 struct bcm_flash2x_cs_info *psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
3106 enum bcm_flash2x_section_val uiHighestPriDSD = 0;
3107 enum bcm_flash2x_section_val uiHighestPriISO = 0;
3108 BOOLEAN SetActiveDSDDone = FALSE;
3109 BOOLEAN SetActiveISODone = FALSE;
3111 /* For 1.x map all the section except DSD0 will be shown as not present
3112 * This part will be used by calibration tool to detect the number of DSD present in Flash.
3114 if (IsFlash2x(Adapter) == FALSE) {
3115 psFlash2xBitMap->ISO_IMAGE2 = 0;
3116 psFlash2xBitMap->ISO_IMAGE1 = 0;
3117 psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */
3118 psFlash2xBitMap->DSD1 = 0;
3119 psFlash2xBitMap->DSD2 = 0;
3120 psFlash2xBitMap->VSA0 = 0;
3121 psFlash2xBitMap->VSA1 = 0;
3122 psFlash2xBitMap->VSA2 = 0;
3123 psFlash2xBitMap->CONTROL_SECTION = 0;
3124 psFlash2xBitMap->SCSI = 0;
3125 psFlash2xBitMap->Reserved0 = 0;
3126 psFlash2xBitMap->Reserved1 = 0;
3127 psFlash2xBitMap->Reserved2 = 0;
3129 return STATUS_SUCCESS;
3132 uiHighestPriDSD = getHighestPriDSD(Adapter);
3133 uiHighestPriISO = getHighestPriISO(Adapter);
3138 if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) {
3139 /* Setting the 0th Bit representing the Section is present or not. */
3140 psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
3142 if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER)
3143 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
3145 /* Calculation for extrating the Access permission */
3146 if (IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
3147 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
3149 if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) {
3150 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT;
3151 SetActiveISODone = TRUE;
3158 if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) {
3159 /* Setting the 0th Bit representing the Section is present or not. */
3160 psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
3162 if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
3163 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
3165 /* Calculation for extrating the Access permission */
3166 if (IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
3167 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
3169 if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) {
3170 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT;
3171 SetActiveISODone = TRUE;
3178 if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) {
3179 /* Setting the 0th Bit representing the Section is present or not. */
3180 psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
3182 if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER)
3183 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
3185 /* Calculation for extrating the Access permission */
3186 if (IsSectionWritable(Adapter, DSD2) == FALSE) {
3187 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
3189 /* Means section is writable */
3190 if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) {
3191 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT;
3192 SetActiveDSDDone = TRUE;
3200 if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) {
3201 /* Setting the 0th Bit representing the Section is present or not. */
3202 psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
3204 if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER)
3205 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
3207 /* Calculation for extrating the Access permission */
3208 if (IsSectionWritable(Adapter, DSD1) == FALSE) {
3209 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
3211 /* Means section is writable */
3212 if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) {
3213 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT;
3214 SetActiveDSDDone = TRUE;
3222 if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) {
3223 /* Setting the 0th Bit representing the Section is present or not. */
3224 psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
3226 if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER)
3227 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
3229 /* Setting Access permission */
3230 if (IsSectionWritable(Adapter, DSD0) == FALSE) {
3231 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
3233 /* Means section is writable */
3234 if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD0)) {
3235 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT;
3236 SetActiveDSDDone = TRUE;
3244 if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) {
3245 /* Setting the 0th Bit representing the Section is present or not. */
3246 psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
3248 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3249 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
3251 /* Calculation for extrating the Access permission */
3252 if (IsSectionWritable(Adapter, VSA0) == FALSE)
3253 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO;
3255 /* By Default section is Active */
3256 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT;
3262 if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) {
3263 /* Setting the 0th Bit representing the Section is present or not. */
3264 psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
3266 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3267 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID;
3269 /* Checking For Access permission */
3270 if (IsSectionWritable(Adapter, VSA1) == FALSE)
3271 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
3273 /* By Default section is Active */
3274 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT;
3280 if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) {
3281 /* Setting the 0th Bit representing the Section is present or not. */
3282 psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
3284 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3285 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
3287 /* Checking For Access permission */
3288 if (IsSectionWritable(Adapter, VSA2) == FALSE)
3289 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
3291 /* By Default section is Active */
3292 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT;
3298 if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) {
3299 /* Setting the 0th Bit representing the Section is present or not. */
3300 psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
3302 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3303 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID;
3305 /* Checking For Access permission */
3306 if (IsSectionWritable(Adapter, SCSI) == FALSE)
3307 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
3309 /* By Default section is Active */
3310 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT;
3316 if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) {
3317 /* Setting the 0th Bit representing the Section is present or not. */
3318 psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
3320 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3321 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
3323 /* Checking For Access permission */
3324 if (IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
3325 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
3327 /* By Default section is Active */
3328 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT;
3332 * For Reserved Sections
3334 psFlash2xBitMap->Reserved0 = 0;
3335 psFlash2xBitMap->Reserved0 = 0;
3336 psFlash2xBitMap->Reserved0 = 0;
3337 BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
3339 return STATUS_SUCCESS;
3343 * BcmSetActiveSection :- Set Active section is used to make priority field highest over other
3344 * section of same type.
3346 * @Adapater :- Bcm Driver Private Data Structure
3347 * @eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
3349 * Return Value:- Make the priorit highest else return erorr code
3353 int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal)
3355 unsigned int SectImagePriority = 0;
3356 int Status = STATUS_SUCCESS;
3358 /* struct bcm_dsd_header sDSD = {0};
3359 * struct bcm_iso_header sISO = {0};
3361 int HighestPriDSD = 0 ;
3362 int HighestPriISO = 0;
3364 Status = IsSectionWritable(Adapter, eFlash2xSectVal);
3365 if (Status != TRUE) {
3366 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal);
3367 return STATUS_FAILURE;
3370 Adapter->bHeaderChangeAllowed = TRUE;
3371 switch (eFlash2xSectVal) {
3374 if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) {
3375 HighestPriISO = getHighestPriISO(Adapter);
3377 if (HighestPriISO == eFlash2xSectVal) {
3378 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
3379 Status = STATUS_SUCCESS;
3383 SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
3385 if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) {
3386 /* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
3387 * We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
3390 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
3391 SectImagePriority = htonl(0x1);
3392 Status = BcmFlash2xBulkWrite(Adapter,
3395 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
3399 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3400 Status = STATUS_FAILURE;
3404 HighestPriISO = getHighestPriISO(Adapter);
3406 if (HighestPriISO == eFlash2xSectVal) {
3407 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
3408 Status = STATUS_SUCCESS;
3412 SectImagePriority = 2;
3415 SectImagePriority = htonl(SectImagePriority);
3417 Status = BcmFlash2xBulkWrite(Adapter,
3420 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
3424 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3428 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3429 Status = STATUS_FAILURE;
3436 if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) {
3437 HighestPriDSD = getHighestPriDSD(Adapter);
3438 if ((HighestPriDSD == eFlash2xSectVal)) {
3439 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal);
3440 Status = STATUS_SUCCESS;
3444 SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1;
3445 if (SectImagePriority <= 0) {
3446 /* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
3447 * We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
3450 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
3451 SectImagePriority = htonl(0x1);
3453 Status = BcmFlash2xBulkWrite(Adapter,
3456 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
3460 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3464 HighestPriDSD = getHighestPriDSD(Adapter);
3466 if ((HighestPriDSD == eFlash2xSectVal)) {
3467 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
3468 Status = STATUS_SUCCESS;
3472 SectImagePriority = htonl(0x2);
3473 Status = BcmFlash2xBulkWrite(Adapter,
3476 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
3480 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3484 HighestPriDSD = getHighestPriDSD(Adapter);
3485 if ((HighestPriDSD == eFlash2xSectVal)) {
3486 Status = STATUS_SUCCESS;
3490 SectImagePriority = 3;
3492 SectImagePriority = htonl(SectImagePriority);
3493 Status = BcmFlash2xBulkWrite(Adapter,
3496 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
3500 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3501 Status = STATUS_FAILURE;
3505 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3506 Status = STATUS_FAILURE;
3513 /* Has to be decided */
3516 Status = STATUS_FAILURE;
3520 Adapter->bHeaderChangeAllowed = FALSE;
3525 * BcmCopyISO - Used only for copying the ISO section
3526 * @Adapater :- Bcm Driver Private Data Structure
3527 * @sCopySectStrut :- Section copy structure
3529 * Return value:- SUCCESS if copies successfully else negative error code
3533 int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut)
3536 enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0;
3537 unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
3538 unsigned int uiTotalDataToCopy = 0;
3539 BOOLEAN IsThisHeaderSector = FALSE;
3540 unsigned int sigOffset = 0;
3541 unsigned int ISOLength = 0;
3542 unsigned int Status = STATUS_SUCCESS;
3543 unsigned int SigBuff[MAX_RW_SIZE];
3546 if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) {
3547 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3548 return STATUS_FAILURE;
3551 Status = BcmFlash2xBulkRead(Adapter,
3553 sCopySectStrut.SrcSection,
3554 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize),
3557 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
3561 ISOLength = htonl(ISOLength);
3562 if (ISOLength % Adapter->uiSectorSize)
3563 ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize);
3565 sigOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber);
3567 Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
3570 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size");
3574 if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) {
3575 eISOReadPart = ISO_IMAGE1;
3576 eISOWritePart = ISO_IMAGE2;
3577 uiReadOffsetWithinPart = 0;
3578 uiWriteOffsetWithinPart = 0;
3580 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
3581 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
3582 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
3583 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
3584 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
3585 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3587 if (uiTotalDataToCopy < ISOLength) {
3588 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3589 Status = STATUS_FAILURE;
3593 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
3594 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
3595 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
3596 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
3597 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
3598 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3600 if (uiTotalDataToCopy < ISOLength) {
3601 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
3602 Status = STATUS_FAILURE;
3606 uiTotalDataToCopy = ISOLength;
3608 CorruptISOSig(Adapter, ISO_IMAGE2);
3609 while (uiTotalDataToCopy) {
3610 if (uiTotalDataToCopy == Adapter->uiSectorSize) {
3611 /* Setting for write of first sector. First sector is assumed to be written in last */
3612 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
3613 eISOReadPart = ISO_IMAGE1;
3614 uiReadOffsetWithinPart = 0;
3615 eISOWritePart = ISO_IMAGE2;
3616 uiWriteOffsetWithinPart = 0;
3617 IsThisHeaderSector = TRUE;
3619 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3620 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
3622 if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
3623 eISOReadPart = ISO_IMAGE1_PART2;
3624 uiReadOffsetWithinPart = 0;
3627 if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
3628 eISOReadPart = ISO_IMAGE1_PART3;
3629 uiReadOffsetWithinPart = 0;
3632 if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
3633 eISOWritePart = ISO_IMAGE2_PART2;
3634 uiWriteOffsetWithinPart = 0;
3637 if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
3638 eISOWritePart = ISO_IMAGE2_PART3;
3639 uiWriteOffsetWithinPart = 0;
3643 Status = BcmFlash2xBulkRead(Adapter,
3646 uiReadOffsetWithinPart,
3647 Adapter->uiSectorSize);
3649 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
3653 if (IsThisHeaderSector == TRUE) {
3654 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
3655 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
3657 for (i = 0; i < MAX_RW_SIZE; i++)
3658 *(Buff + sigOffset + i) = 0xFF;
3660 Adapter->bHeaderChangeAllowed = TRUE;
3661 Status = BcmFlash2xBulkWrite(Adapter,
3664 uiWriteOffsetWithinPart,
3665 Adapter->uiSectorSize,
3668 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
3672 Adapter->bHeaderChangeAllowed = FALSE;
3673 if (IsThisHeaderSector == TRUE) {
3674 WriteToFlashWithoutSectorErase(Adapter,
3679 IsThisHeaderSector = FALSE;
3681 /* subtracting the written Data */
3682 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
3686 if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) {
3687 eISOReadPart = ISO_IMAGE2;
3688 eISOWritePart = ISO_IMAGE1;
3689 uiReadOffsetWithinPart = 0;
3690 uiWriteOffsetWithinPart = 0;
3692 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
3693 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
3694 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
3695 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
3696 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
3697 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3699 if (uiTotalDataToCopy < ISOLength) {
3700 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3701 Status = STATUS_FAILURE;
3705 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
3706 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
3707 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
3708 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
3709 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
3710 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3712 if (uiTotalDataToCopy < ISOLength) {
3713 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
3714 Status = STATUS_FAILURE;
3718 uiTotalDataToCopy = ISOLength;
3720 CorruptISOSig(Adapter, ISO_IMAGE1);
3722 while (uiTotalDataToCopy) {
3723 if (uiTotalDataToCopy == Adapter->uiSectorSize) {
3724 /* Setting for write of first sector. First sector is assumed to be written in last */
3725 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
3726 eISOReadPart = ISO_IMAGE2;
3727 uiReadOffsetWithinPart = 0;
3728 eISOWritePart = ISO_IMAGE1;
3729 uiWriteOffsetWithinPart = 0;
3730 IsThisHeaderSector = TRUE;
3732 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3733 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
3735 if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
3736 eISOReadPart = ISO_IMAGE2_PART2;
3737 uiReadOffsetWithinPart = 0;
3740 if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
3741 eISOReadPart = ISO_IMAGE2_PART3;
3742 uiReadOffsetWithinPart = 0;
3745 if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
3746 eISOWritePart = ISO_IMAGE1_PART2;
3747 uiWriteOffsetWithinPart = 0;
3750 if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
3751 eISOWritePart = ISO_IMAGE1_PART3;
3752 uiWriteOffsetWithinPart = 0;
3756 Status = BcmFlash2xBulkRead(Adapter,
3759 uiReadOffsetWithinPart,
3760 Adapter->uiSectorSize);
3762 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
3766 if (IsThisHeaderSector == TRUE) {
3767 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
3768 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
3770 for (i = 0; i < MAX_RW_SIZE; i++)
3771 *(Buff + sigOffset + i) = 0xFF;
3773 Adapter->bHeaderChangeAllowed = TRUE;
3774 Status = BcmFlash2xBulkWrite(Adapter,
3777 uiWriteOffsetWithinPart,
3778 Adapter->uiSectorSize,
3781 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
3785 Adapter->bHeaderChangeAllowed = FALSE;
3786 if (IsThisHeaderSector == TRUE) {
3787 WriteToFlashWithoutSectorErase(Adapter,
3793 IsThisHeaderSector = FALSE;
3796 /* subtracting the written Data */
3797 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
3807 * BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
3808 * It will corrupt the sig, if Section is writable, by making first bytes as zero.
3809 * @Adapater :- Bcm Driver Private Data Structure
3810 * @eFlash2xSectionVal :- Flash section val which has header
3813 * Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
3814 * Failure :-Return negative error code
3817 int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
3819 int Status = STATUS_SUCCESS;
3821 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal);
3823 if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) {
3824 Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
3825 } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) {
3826 Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
3828 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal);
3829 return STATUS_SUCCESS;
3835 *BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
3836 * header and Write Permission.
3837 * @Adapater :- Bcm Driver Private Data Structure
3838 * @eFlashSectionVal :- Flash section val which has header
3841 * Success :- If Section is present and writable write the sig and return STATUS_SUCCESS
3842 * Failure :-Return negative error code
3845 int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
3847 unsigned int uiSignature = 0;
3848 unsigned int uiOffset = 0;
3850 /* struct bcm_dsd_header dsdHeader = {0}; */
3851 if (Adapter->bSigCorrupted == FALSE) {
3852 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n");
3853 return STATUS_SUCCESS;
3856 if (Adapter->bAllDSDWriteAllow == FALSE) {
3857 if (IsSectionWritable(Adapter, eFlashSectionVal) == FALSE) {
3858 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature");
3859 return SECTOR_IS_NOT_WRITABLE;
3863 if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) {
3864 uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER);
3865 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader;
3867 uiOffset += FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber);
3869 if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
3870 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig");
3871 return STATUS_FAILURE;
3873 } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) {
3874 uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
3876 uiOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber);
3877 if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
3878 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig");
3879 return STATUS_FAILURE;
3882 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
3883 return STATUS_FAILURE;
3886 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature");
3888 Adapter->bHeaderChangeAllowed = TRUE;
3889 Adapter->bSigCorrupted = FALSE;
3890 BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE);
3891 Adapter->bHeaderChangeAllowed = FALSE;
3893 return STATUS_SUCCESS;
3897 * validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
3898 * if requested Bytes goes beyond the Requested section, it reports error.
3899 * @Adapater :- Bcm Driver Private Data Structure
3900 * @psFlash2xReadWrite :-Flash2x Read/write structure pointer
3902 * Return values:-Return TRUE is request is valid else FALSE.
3905 int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite)
3907 unsigned int uiNumOfBytes = 0;
3908 unsigned int uiSectStartOffset = 0;
3909 unsigned int uiSectEndOffset = 0;
3911 uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
3913 if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) {
3914 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exixt in Flash", psFlash2xReadWrite->Section);
3917 uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section);
3918 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section);
3919 if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) {
3920 if (psFlash2xReadWrite->Section == ISO_IMAGE1) {
3921 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) -
3922 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) +
3923 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) -
3924 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) +
3925 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) -
3926 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3);
3927 } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) {
3928 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) -
3929 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) +
3930 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) -
3931 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART2) +
3932 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART3) -
3933 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3);
3936 /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset
3937 * it should be added in startoffset. so that check done in last of this function can be valued.
3939 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset;
3941 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset);
3943 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section);
3945 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset);
3947 /* Checking the boundary condition */
3948 if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
3951 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
3957 * IsFlash2x :- check for Flash 2.x
3958 * Adapater :- Bcm Driver Private Data Structure
3961 * return TRUE if flah2.x of hgher version else return false.
3964 int IsFlash2x(struct bcm_mini_adapter *Adapter)
3966 if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
3973 * GetFlashBaseAddr :- Calculate the Flash Base address
3974 * @Adapater :- Bcm Driver Private Data Structure
3977 * Success :- Base Address of the Flash
3980 static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
3982 unsigned int uiBaseAddr = 0;
3984 if (Adapter->bDDRInitDone) {
3986 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3987 * In case of Raw Read... use the default value
3989 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
3990 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
3991 uiBaseAddr = Adapter->uiFlashBaseAdd;
3993 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
3996 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3997 * In case of Raw Read... use the default value
3999 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
4000 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
4001 uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4003 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
4010 * BcmCopySection :- This API is used to copy the One section in another. Both section should
4011 * be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
4013 * @Adapater :- Bcm Driver Private Data Structure
4014 * @SrcSection :- Source section From where data has to be copied
4015 * @DstSection :- Destination section to which data has to be copied
4016 * @offset :- Offset from/to where data has to be copied from one section to another.
4017 * @numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
4018 * in case of numofBytes equal zero complete section will be copied.
4020 * Success : Return STATUS_SUCCESS
4021 * Faillure :- return negative error code
4024 int BcmCopySection(struct bcm_mini_adapter *Adapter,
4025 enum bcm_flash2x_section_val SrcSection,
4026 enum bcm_flash2x_section_val DstSection,
4027 unsigned int offset,
4028 unsigned int numOfBytes)
4030 unsigned int BuffSize = 0;
4031 unsigned int BytesToBeCopied = 0;
4032 PUCHAR pBuff = NULL;
4033 int Status = STATUS_SUCCESS;
4035 if (SrcSection == DstSection) {
4036 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again");
4040 if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) {
4041 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection");
4045 if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) {
4046 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection");
4050 /* if offset zero means have to copy complete secton */
4051 if (numOfBytes == 0) {
4052 numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection)
4053 - BcmGetSectionValStartOffset(Adapter, SrcSection);
4055 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes);
4058 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection)
4059 - BcmGetSectionValStartOffset(Adapter, SrcSection)) {
4060 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
4061 offset, numOfBytes);
4065 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection)
4066 - BcmGetSectionValStartOffset(Adapter, DstSection)) {
4067 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
4068 offset, numOfBytes);
4072 if (numOfBytes > Adapter->uiSectorSize)
4073 BuffSize = Adapter->uiSectorSize;
4075 BuffSize = numOfBytes;
4077 pBuff = kzalloc(BuffSize, GFP_KERNEL);
4079 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. ");
4083 BytesToBeCopied = Adapter->uiSectorSize;
4084 if (offset % Adapter->uiSectorSize)
4085 BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
4086 if (BytesToBeCopied > numOfBytes)
4087 BytesToBeCopied = numOfBytes;
4089 Adapter->bHeaderChangeAllowed = TRUE;
4092 Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied);
4094 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied);
4097 Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, FALSE);
4099 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied);
4102 offset = offset + BytesToBeCopied;
4103 numOfBytes = numOfBytes - BytesToBeCopied;
4105 if (numOfBytes > Adapter->uiSectorSize)
4106 BytesToBeCopied = Adapter->uiSectorSize;
4108 BytesToBeCopied = numOfBytes;
4110 } while (numOfBytes > 0);
4113 Adapter->bHeaderChangeAllowed = FALSE;
4119 * SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
4120 * @Adapater :- Bcm Driver Private Data Structure
4121 * @pBuff :- Data buffer that has to be written in sector having the header map.
4122 * @uiOffset :- Flash offset that has to be written.
4125 * Success :- On success return STATUS_SUCCESS
4126 * Faillure :- Return negative error code
4129 int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset)
4131 unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0;
4132 BOOLEAN bHasHeader = FALSE;
4133 PUCHAR pTempBuff = NULL;
4134 unsigned int uiSectAlignAddr = 0;
4135 unsigned int sig = 0;
4137 /* making the offset sector aligned */
4138 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4140 if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) ||
4141 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) ||
4142 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) {
4143 /* offset from the sector boundary having the header map */
4144 offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
4145 HeaderSizeToProtect = sizeof(struct bcm_dsd_header);
4149 if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) ||
4150 uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) {
4151 offsetToProtect = 0;
4152 HeaderSizeToProtect = sizeof(struct bcm_iso_header);
4155 /* If Header is present overwrite passed buffer with this */
4156 if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) {
4157 pTempBuff = kzalloc(HeaderSizeToProtect, GFP_KERNEL);
4159 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed");
4163 BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect);
4164 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect);
4165 /* Replace Buffer content with Header */
4166 memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect);
4170 if (bHasHeader && Adapter->bSigCorrupted) {
4171 sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber)));
4173 if ((sig & 0xFF000000) != CORRUPTED_PATTERN) {
4174 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore");
4175 Adapter->bSigCorrupted = FALSE;
4176 return STATUS_SUCCESS;
4178 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig);
4179 *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER);
4180 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only");
4181 Adapter->bSigCorrupted = FALSE;
4184 return STATUS_SUCCESS;
4188 * BcmDoChipSelect : This will selcet the appropriate chip for writing.
4189 * @Adapater :- Bcm Driver Private Data Structure
4192 * Select the Appropriate chip and retrn status Success
4194 static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset)
4196 unsigned int FlashConfig = 0;
4198 unsigned int GPIOConfig = 0;
4199 unsigned int PartNum = 0;
4201 ChipNum = offset / FLASH_PART_SIZE;
4204 * Chip Select mapping to enable flash0.
4205 * To select flash 0, we have to OR with (0<<12).
4206 * ORing 0 will have no impact so not doing that part.
4207 * In future if Chip select value changes from 0 to non zero,
4208 * That needs be taken care with backward comaptibility. No worries for now.
4212 * SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
4213 * if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
4214 * Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
4215 * power down modes (Idle mode/shutdown mode), the values in the register will be different.
4218 if (Adapter->SelectedChip == ChipNum)
4219 return STATUS_SUCCESS;
4221 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); */
4222 Adapter->SelectedChip = ChipNum;
4224 /* bit[13..12] will select the appropriate chip */
4225 rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4226 rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4234 GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
4238 GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
4242 GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
4246 /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
4247 * nothing to do... can return immediately.
4248 * ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
4249 * Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
4250 * These values are not written by host other than during CHIP_SELECT.
4252 if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
4253 return STATUS_SUCCESS;
4255 /* clearing the bit[13..12] */
4256 FlashConfig &= 0xFFFFCFFF;
4257 FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); /* 00 */
4259 wrmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4262 wrmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4265 return STATUS_SUCCESS;
4268 int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
4270 unsigned int uiDSDsig = 0;
4271 /* unsigned int sigoffsetInMap = 0;
4272 * struct bcm_dsd_header dsdHeader = {0};
4275 /* sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader; */
4277 if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) {
4278 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for DSDs");
4279 return STATUS_FAILURE;
4281 BcmFlash2xBulkRead(Adapter,
4284 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber),
4287 uiDSDsig = ntohl(uiDSDsig);
4288 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig);
4293 int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
4295 /* unsigned int priOffsetInMap = 0 ; */
4296 unsigned int uiDSDPri = STATUS_FAILURE;
4297 /* struct bcm_dsd_header dsdHeader = {0};
4298 * priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
4300 if (IsSectionWritable(Adapter, dsd)) {
4301 if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) {
4302 BcmFlash2xBulkRead(Adapter,
4305 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
4308 uiDSDPri = ntohl(uiDSDPri);
4309 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri);
4316 enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
4318 int DSDHighestPri = STATUS_FAILURE;
4320 enum bcm_flash2x_section_val HighestPriDSD = 0;
4322 if (IsSectionWritable(Adapter, DSD2)) {
4323 DSDHighestPri = ReadDSDPriority(Adapter, DSD2);
4324 HighestPriDSD = DSD2;
4327 if (IsSectionWritable(Adapter, DSD1)) {
4328 DsdPri = ReadDSDPriority(Adapter, DSD1);
4329 if (DSDHighestPri < DsdPri) {
4330 DSDHighestPri = DsdPri;
4331 HighestPriDSD = DSD1;
4335 if (IsSectionWritable(Adapter, DSD0)) {
4336 DsdPri = ReadDSDPriority(Adapter, DSD0);
4337 if (DSDHighestPri < DsdPri) {
4338 DSDHighestPri = DsdPri;
4339 HighestPriDSD = DSD0;
4343 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri);
4345 return HighestPriDSD;
4348 int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
4350 unsigned int uiISOsig = 0;
4351 /* unsigned int sigoffsetInMap = 0;
4352 * struct bcm_iso_header ISOHeader = {0};
4353 * sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
4355 if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) {
4356 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs");
4357 return STATUS_FAILURE;
4359 BcmFlash2xBulkRead(Adapter,
4362 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber),
4365 uiISOsig = ntohl(uiISOsig);
4366 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig);
4371 int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
4373 unsigned int ISOPri = STATUS_FAILURE;
4374 if (IsSectionWritable(Adapter, iso)) {
4375 if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) {
4376 BcmFlash2xBulkRead(Adapter,
4379 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
4382 ISOPri = ntohl(ISOPri);
4383 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri);
4390 enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
4392 int ISOHighestPri = STATUS_FAILURE;
4394 enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL;
4396 if (IsSectionWritable(Adapter, ISO_IMAGE2)) {
4397 ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2);
4398 HighestPriISO = ISO_IMAGE2;
4401 if (IsSectionWritable(Adapter, ISO_IMAGE1)) {
4402 ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1);
4403 if (ISOHighestPri < ISOPri) {
4404 ISOHighestPri = ISOPri;
4405 HighestPriISO = ISO_IMAGE1;
4409 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest ISO :%x and its Pri :%x", HighestPriISO, ISOHighestPri);
4411 return HighestPriISO;
4414 int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
4416 enum bcm_flash2x_section_val eFlash2xSectionVal,
4417 unsigned int uiOffset,
4418 unsigned int uiNumBytes)
4420 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
4421 unsigned int uiTemp = 0, value = 0;
4423 unsigned int uiPartOffset = 0;
4425 unsigned int uiStartOffset = 0;
4426 /* Adding section start address */
4427 int Status = STATUS_SUCCESS;
4428 PUCHAR pcBuff = (PUCHAR)pBuff;
4430 if (uiNumBytes % Adapter->ulFlashWriteSize) {
4431 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
4432 return STATUS_FAILURE;
4435 uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
4437 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
4438 return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
4440 uiOffset = uiOffset + uiStartOffset;
4442 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
4443 Status = bcmflash_raw_writenoerase((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), pcBuff, uiNumBytes);
4445 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4447 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
4449 Adapter->SelectedChip = RESET_CHIP_SELECT;
4450 BcmDoChipSelect(Adapter, uiOffset);
4451 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
4453 for (i = 0 ; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
4454 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
4455 Status = flashByteWrite(Adapter, uiPartOffset, pcBuff);
4457 Status = flashWrite(Adapter, uiPartOffset, pcBuff);
4459 if (Status != STATUS_SUCCESS)
4462 pcBuff = pcBuff + Adapter->ulFlashWriteSize;
4463 uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize;
4465 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4466 Adapter->SelectedChip = RESET_CHIP_SELECT;
4472 BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
4474 BOOLEAN SectionPresent = FALSE;
4478 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
4479 (IsNonCDLessDevice(Adapter) == FALSE))
4480 SectionPresent = TRUE;
4483 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
4484 (IsNonCDLessDevice(Adapter) == FALSE))
4485 SectionPresent = TRUE;
4488 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
4489 SectionPresent = TRUE;
4492 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
4493 SectionPresent = TRUE;
4496 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
4497 SectionPresent = TRUE;
4500 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
4501 SectionPresent = TRUE;
4504 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
4505 SectionPresent = TRUE;
4508 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
4509 SectionPresent = TRUE;
4512 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
4513 SectionPresent = TRUE;
4515 case CONTROL_SECTION:
4516 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
4517 SectionPresent = TRUE;
4520 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
4521 SectionPresent = FALSE;
4524 return SectionPresent;
4527 int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
4529 int offset = STATUS_FAILURE;
4532 if (IsSectionExistInFlash(Adapter, Section) == FALSE) {
4533 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exixt", Section);
4537 offset = BcmGetSectionValStartOffset(Adapter, Section);
4538 if (offset == INVALID_OFFSET) {
4539 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exixt", Section);
4543 if (IsSectionExistInVendorInfo(Adapter, Section))
4544 return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
4546 Status = IsOffsetWritable(Adapter, offset);
4550 static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
4552 PUCHAR pBuff = NULL;
4553 unsigned int sig = 0;
4554 unsigned int uiOffset = 0;
4555 unsigned int BlockStatus = 0;
4556 unsigned int uiSectAlignAddr = 0;
4558 Adapter->bSigCorrupted = FALSE;
4559 if (Adapter->bAllDSDWriteAllow == FALSE) {
4560 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
4561 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
4562 return SECTOR_IS_NOT_WRITABLE;
4566 pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL);
4568 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4572 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header);
4573 uiOffset -= MAX_RW_SIZE;
4575 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
4577 sig = *((PUINT)(pBuff + 12));
4579 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
4580 /* Now corrupting the sig by corrupting 4th last Byte. */
4583 if (sig == DSD_IMAGE_MAGIC_NUMBER) {
4584 Adapter->bSigCorrupted = TRUE;
4585 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) {
4586 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4587 BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
4589 WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal,
4590 (uiOffset + 12), BYTE_WRITE_SUPPORT);
4592 BcmRestoreBlockProtectStatus(Adapter, BlockStatus);
4596 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4597 uiOffset, MAX_RW_SIZE);
4600 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
4603 return STATUS_FAILURE;
4607 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
4609 return STATUS_SUCCESS;
4612 static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
4614 PUCHAR pBuff = NULL;
4615 unsigned int sig = 0;
4616 unsigned int uiOffset = 0;
4618 Adapter->bSigCorrupted = FALSE;
4620 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
4621 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
4622 return SECTOR_IS_NOT_WRITABLE;
4625 pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL);
4627 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4633 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
4635 sig = *((PUINT)pBuff);
4638 /* corrupt signature */
4641 if (sig == ISO_IMAGE_MAGIC_NUMBER) {
4642 Adapter->bSigCorrupted = TRUE;
4643 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4644 uiOffset, Adapter->ulFlashWriteSize);
4646 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
4649 return STATUS_FAILURE;
4652 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
4653 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
4656 return STATUS_SUCCESS;
4659 BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter)
4661 if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)