PM / sleep: Asynchronous threads for suspend_noirq
[linux/fpc-iii.git] / drivers / staging / bcm / nvm.c
blobfca164f51f4b117623e23e48b02d35007c3c3e81
1 #include "headers.h"
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,
39 PUINT pBuffer,
40 unsigned int uiOffset,
41 unsigned int uiNumBytes);
43 static int BeceemFlashBulkWrite(
44 struct bcm_mini_adapter *Adapter,
45 PUINT pBuffer,
46 unsigned int uiOffset,
47 unsigned int uiNumBytes,
48 bool bVerify);
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.
58 * Arguments:
59 * Adapter - ptr to Adapter object instance
60 * Returns:
61 * OSAL_STATUS_CODE
63 static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter)
65 UCHAR uiData = 0;
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) {
76 value = 0;
77 uiStatus = 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....");
81 break;
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));
90 value = 0;
91 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
92 uiData = (UCHAR)value;
94 break;
97 dwRetries--;
98 if (dwRetries == 0) {
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);
102 return uiData;
104 if (!(dwRetries%RETRIES_PER_DELAY))
105 udelay(1000);
106 uiStatus = 0;
108 return uiData;
109 } /* ReadEEPROMStatusRegister */
112 * Procedure: ReadBeceemEEPROMBulk
114 * Description: This routine reads 16Byte data from EEPROM
116 * Arguments:
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.
121 * Returns:
122 * OSAL_STATUS_CODE:
125 int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,
126 DWORD dwAddress,
127 DWORD *pdwData,
128 DWORD dwNumWords)
130 DWORD dwIndex = 0;
131 DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
132 unsigned int uiStatus = 0;
133 unsigned int value = 0;
134 unsigned int value1 = 0;
135 UCHAR *pvalue;
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));
140 value = 0;
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) {
151 uiStatus = 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...");
155 return -ENODEV;
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));
167 break;
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)
175 udelay(800);
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));
180 break;
184 uiStatus = 0;
186 dwRetries--;
187 if (dwRetries == 0) {
188 value = 0;
189 value1 = 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))
198 udelay(1000);
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);
205 value = 0;
206 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
208 pvalue[0] = value;
210 value = 0;
211 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
213 pvalue[1] = value;
215 value = 0;
216 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
218 pvalue[2] = value;
220 value = 0;
221 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
223 pvalue[3] = 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.
235 * Arguments:
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.
240 * Returns:
241 * OSAL_STATUS_CODE:
244 int ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter,
245 DWORD uiOffset,
246 DWORD *pBuffer)
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
260 * next page too.
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)
272 int Status;
273 unsigned char puMacAddr[6];
275 Status = BeceemNVMRead(Adapter,
276 (PUINT)&puMacAddr[0],
277 INIT_PARAMS_1_MACADDRESS_ADDRESS,
278 MAC_ADDRESS_SIZE);
280 if (Status == STATUS_SUCCESS)
281 memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
283 return Status;
287 * Procedure: BeceemEEPROMBulkRead
289 * Description: Reads the EEPROM and returns the Data.
291 * Arguments:
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.
297 * Returns:
298 * OSAL_STATUS_SUCCESS - if EEPROM read is successful.
299 * <FAILURE> - if failed.
302 int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter,
303 PUINT pBuffer,
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);
325 } else {
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)
335 return -1;
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;
347 } else {
348 uiFailureRetries++;
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);
354 uiOffset += 4;
355 uiBytesRemaining -= 4;
356 uiIndex += 4;
357 } else {
358 uiFailureRetries++;
359 mdelay(3); /* sleep for a while before retry... */
361 } else {
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;
368 } else {
369 uiFailureRetries++;
370 mdelay(3); /* sleep for a while before retry... */
375 return 0;
379 * Procedure: BeceemFlashBulkRead
381 * Description: Reads the FLASH and returns the Data.
383 * Arguments:
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.
389 * Returns:
390 * OSAL_STATUS_SUCCESS - if FLASH read is successful.
391 * <FAILURE> - if failed.
394 static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter,
395 PUINT pBuffer,
396 unsigned int uiOffset,
397 unsigned int uiNumBytes)
399 unsigned int uiIndex = 0;
400 unsigned int uiBytesToRead = uiNumBytes;
401 int Status = 0;
402 unsigned int uiPartOffset = 0;
403 int bytes;
405 if (Adapter->device_removed) {
406 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed");
407 return -ENODEV;
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);
415 return Status;
416 #endif
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);
428 if (bytes < 0) {
429 Status = bytes;
430 Adapter->SelectedChip = RESET_CHIP_SELECT;
431 return Status;
434 uiIndex += uiBytesToRead;
435 uiOffset += uiBytesToRead;
436 uiNumBytes -= uiBytesToRead;
439 while (uiNumBytes) {
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);
446 if (bytes < 0) {
447 Status = bytes;
448 break;
451 uiIndex += uiBytesToRead;
452 uiOffset += uiBytesToRead;
453 uiNumBytes -= uiBytesToRead;
455 Adapter->SelectedChip = RESET_CHIP_SELECT;
456 return Status;
460 * Procedure: BcmGetFlashSize
462 * Description: Finds the size of FLASH.
464 * Arguments:
465 * Adapter - ptr to Adapter object instance
467 * Returns:
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);
476 else
477 return 32 * 1024;
481 * Procedure: BcmGetEEPROMSize
483 * Description: Finds the size of EEPROM.
485 * Arguments:
486 * Adapter - ptr to Adapter object instance
488 * Returns:
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);
510 if (uiData == BECM)
511 return uiIndex * 1024;
513 } else {
515 * EEPROM may not be present or not programmed
517 uiData = 0xBABEFACE;
518 if (BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE) == 0) {
519 uiData = 0;
520 for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) {
521 BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4);
522 if (uiData == 0xBABEFACE)
523 return uiIndex * 1024;
527 return 0;
531 * Procedure: FlashSectorErase
533 * Description: Finds the sector size of the FLASH.
535 * Arguments:
536 * Adapter - ptr to Adapter object instance
537 * addr - sector start address
538 * numOfSectors - number of sectors to be erased.
540 * Returns:
541 * OSAL_STATUS_CODE
545 static int FlashSectorErase(struct bcm_mini_adapter *Adapter,
546 unsigned int addr,
547 unsigned int numOfSectors)
549 unsigned int iIndex = 0, iRetries = 0;
550 unsigned int uiStatus = 0;
551 unsigned int value;
552 int bytes;
554 for (iIndex = 0; iIndex < numOfSectors; iIndex++) {
555 value = 0x06000000;
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));
560 iRetries = 0;
562 do {
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));
570 if (bytes < 0) {
571 uiStatus = bytes;
572 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
573 return uiStatus;
575 iRetries++;
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.
580 mdelay(10);
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;
590 return 0;
593 * Procedure: flashByteWrite
595 * Description: Performs Byte by Byte write to flash
597 * Arguments:
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.
601 * Returns:
602 * OSAL_STATUS_CODE
606 static int flashByteWrite(struct bcm_mini_adapter *Adapter,
607 unsigned int uiOffset,
608 PVOID pData)
610 unsigned int uiStatus = 0;
611 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
612 unsigned int value;
613 ULONG ulData = *(PUCHAR)pData;
614 int bytes;
616 * need not write 0xFF because write requires an erase and erase will
617 * make whole sector 0xFF.
620 if (0xFF == ulData)
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;
640 /* __udelay(950); */
642 do {
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;
648 /* __udelay(1); */
649 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
650 if (bytes < 0) {
651 uiStatus = bytes;
652 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
653 return uiStatus;
655 iRetries--;
656 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
657 udelay(1000);
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
674 * Arguments:
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.
678 * Returns:
679 * OSAL_STATUS_CODE
683 static int flashWrite(struct bcm_mini_adapter *Adapter,
684 unsigned int uiOffset,
685 PVOID pData)
687 /* unsigned int uiStatus = 0;
688 * int iRetries = 0;
689 * unsigned int uiReadBack = 0;
691 unsigned int uiStatus = 0;
692 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
693 unsigned int value;
694 unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
695 int bytes;
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))
701 return 0;
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;
715 /* __udelay(950); */
716 do {
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;
722 /* __udelay(1); */
723 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
724 if (bytes < 0) {
725 uiStatus = bytes;
726 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
727 return uiStatus;
730 iRetries--;
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))
737 udelay(1000);
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
753 * Arguments:
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.
757 * Returns:
758 * OSAL_STATUS_CODE
761 static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter,
762 unsigned int uiOffset,
763 PVOID pData)
765 unsigned int uiStatus = 0;
766 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
767 ULONG ulData = *(PUCHAR)pData;
768 unsigned int value;
769 int bytes;
772 * need not write 0xFFFFFFFF because write requires an erase and erase will
773 * make whole sector 0xFFFFFFFF.
776 if (0xFF == ulData)
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;
796 /* msleep(1); */
798 do {
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;
804 /* __udelay(1); */
805 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
806 if (bytes < 0) {
807 uiStatus = bytes;
808 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
809 return uiStatus;
812 iRetries--;
813 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
814 udelay(1000);
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
830 * Arguments:
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.
834 * Returns:
835 * OSAL_STATUS_CODE
839 static int flashWriteStatus(struct bcm_mini_adapter *Adapter,
840 unsigned int uiOffset,
841 PVOID pData)
843 unsigned int uiStatus = 0;
844 int iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; /* 3 */
845 /* unsigned int uiReadBack = 0; */
846 unsigned int value;
847 unsigned int uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
848 int bytes;
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))
855 return 0;
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;
867 /* __udelay(1); */
869 do {
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;
875 /* __udelay(1); */
876 bytes = rdmalt(Adapter, FLASH_SPI_READQ_REG, &uiStatus, sizeof(uiStatus));
877 if (bytes < 0) {
878 uiStatus = bytes;
879 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Reading status of FLASH_SPI_READQ_REG fails");
880 return uiStatus;
882 iRetries--;
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))
889 udelay(1000);
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.
906 * Arguments:
907 * Adapter - ptr to Adapter object instance
908 * ulWriteStatus -Original status
909 * Returns:
910 * <VOID>
914 static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus)
916 unsigned int value;
917 value = (FLASH_CMD_WRITE_ENABLE << 24);
918 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
920 udelay(20);
921 value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
922 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
923 udelay(20);
927 * Procedure: BcmFlashUnProtectBlock
929 * Description: UnProtects appropriate blocks for writing.
931 * Arguments:
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.
934 * Returns:
935 * ULONG - Status value before UnProtect.
939 static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned int uiOffset, unsigned int uiLength)
941 ULONG ulStatus = 0;
942 ULONG ulWriteStatus = 0;
943 unsigned int value;
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));
955 udelay(10);
957 * Read status will be WWXXYYZZ. We have to take only WW.
959 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
960 ulStatus >>= 24;
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
969 if (ulStatus) {
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);
998 } else {
1000 * Unblock all.
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));
1008 udelay(20);
1009 value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
1010 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1011 udelay(20);
1014 return ulStatus;
1018 * Procedure: BeceemFlashBulkWrite
1020 * Description: Performs write to the flash
1022 * Arguments:
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.
1028 * Returns:
1029 * OSAL_STATUS_CODE
1033 static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter,
1034 PUINT pBuffer,
1035 unsigned int uiOffset,
1036 unsigned int uiNumBytes,
1037 bool bVerify)
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};
1048 ULONG ulStatus = 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);
1056 return Status;
1057 #endif
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);
1070 if (!pTempBuff)
1071 goto BeceemFlashBulkWrite_EXIT;
1073 * check if the data to be written is overlapped across sectors
1075 if (uiOffset+uiNumBytes < uiSectBoundary) {
1076 uiNumSectTobeRead = 1;
1077 } else {
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)) {
1088 index = 0;
1089 uiTemp = uiNumSectTobeRead;
1090 while (uiTemp) {
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;
1098 index = index + 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,
1111 (PUINT)pTempBuff,
1112 uiOffsetFromSectStart,
1113 Adapter->uiSectorSize)) {
1114 Status = -1;
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));
1127 } else {
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) {
1140 Status = -1;
1141 goto BeceemFlashBulkWrite_EXIT;
1144 if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) {
1145 Status = -1;
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;
1165 } else {
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));
1178 if (ulStatus) {
1179 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1180 ulStatus = 0;
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));
1193 * Cleanup.
1195 BeceemFlashBulkWrite_EXIT:
1196 if (ulStatus)
1197 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1199 kfree(pTempBuff);
1201 Adapter->SelectedChip = RESET_CHIP_SELECT;
1202 return Status;
1206 * Procedure: BeceemFlashBulkWriteStatus
1208 * Description: Writes to Flash. Checks the SPI status after each write.
1210 * Arguments:
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.
1216 * Returns:
1217 * OSAL_STATUS_CODE
1221 static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter,
1222 PUINT pBuffer,
1223 unsigned int uiOffset,
1224 unsigned int uiNumBytes,
1225 bool bVerify)
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};
1236 ULONG ulStatus = 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);
1253 if (!pTempBuff)
1254 goto BeceemFlashBulkWriteStatus_EXIT;
1257 * check if the data to be written is overlapped across sectors
1259 if (uiOffset+uiNumBytes < uiSectBoundary) {
1260 uiNumSectTobeRead = 1;
1261 } else {
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)) {
1269 index = 0;
1270 uiTemp = uiNumSectTobeRead;
1271 while (uiTemp) {
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;
1279 index = index + 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,
1289 (PUINT)pTempBuff,
1290 uiOffsetFromSectStart,
1291 Adapter->uiSectorSize)) {
1292 Status = -1;
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));
1302 } else {
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) {
1313 Status = -1;
1314 goto BeceemFlashBulkWriteStatus_EXIT;
1317 if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) {
1318 Status = -1;
1319 goto BeceemFlashBulkWriteStatus_EXIT;
1323 if (bVerify) {
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;
1334 if (ulStatus) {
1335 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1336 ulStatus = 0;
1339 uiCurrSectOffsetAddr = 0;
1340 uiSectAlignAddr = uiSectBoundary;
1341 uiSectBoundary += Adapter->uiSectorSize;
1342 uiOffsetFromSectStart += Adapter->uiSectorSize;
1343 uiNumSectTobeRead--;
1346 * Cleanup.
1348 BeceemFlashBulkWriteStatus_EXIT:
1349 if (ulStatus)
1350 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
1352 kfree(pTempBuff);
1353 Adapter->SelectedChip = RESET_CHIP_SELECT;
1354 return Status;
1358 * Procedure: PropagateCalParamsFromFlashToMemory
1360 * Description: Dumps the calibration section of EEPROM to DDR.
1362 * Arguments:
1363 * Adapter - ptr to Adapter object instance
1364 * Returns:
1365 * OSAL_STATUS_CODE
1369 int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter)
1371 PCHAR pBuff, pPtr;
1372 unsigned int uiEepromSize = 0;
1373 unsigned int uiBytesToCopy = 0;
1374 /* unsigned int uiIndex = 0; */
1375 unsigned int uiCalStartAddr = EEPROM_CALPARAM_START;
1376 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1377 unsigned int value;
1378 int Status = 0;
1381 * Write the signature first. This will ensure firmware does not access EEPROM.
1383 value = 0xbeadbead;
1384 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
1385 value = 0xbeadbead;
1386 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
1388 if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4))
1389 return -1;
1391 uiEepromSize = ntohl(uiEepromSize);
1392 uiEepromSize >>= 16;
1395 * subtract the auto init section size
1397 uiEepromSize -= EEPROM_CALPARAM_START;
1399 if (uiEepromSize > 1024 * 1024)
1400 return -1;
1402 pBuff = kmalloc(uiEepromSize, GFP_KERNEL);
1403 if (pBuff == NULL)
1404 return -ENOMEM;
1406 if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) {
1407 kfree(pBuff);
1408 return -1;
1411 pPtr = pBuff;
1413 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
1415 while (uiBytesToCopy) {
1416 Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy);
1417 if (Status) {
1418 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status);
1419 break;
1422 pPtr += uiBytesToCopy;
1423 uiEepromSize -= uiBytesToCopy;
1424 uiMemoryLoc += uiBytesToCopy;
1425 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
1428 kfree(pBuff);
1429 return Status;
1433 * Procedure: BeceemEEPROMReadBackandVerify
1435 * Description: Read back the data written and verifies.
1437 * Arguments:
1438 * Adapter - ptr to Adapter object instance
1439 * pBuffer - Data to be written.
1440 * uiOffset - Offset of the flash where data needs to be written to.
1441 * uiNumBytes - Number of bytes to be written.
1442 * Returns:
1443 * OSAL_STATUS_CODE
1447 static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter,
1448 PUINT pBuffer,
1449 unsigned int uiOffset,
1450 unsigned int uiNumBytes)
1452 unsigned int uiRdbk = 0;
1453 unsigned int uiIndex = 0;
1454 unsigned int uiData = 0;
1455 unsigned int auiData[4] = {0};
1457 while (uiNumBytes) {
1458 if (Adapter->device_removed)
1459 return -1;
1461 if (uiNumBytes >= MAX_RW_SIZE) {
1462 /* for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. */
1463 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
1465 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) {
1466 /* re-write */
1467 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, false);
1468 mdelay(3);
1469 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
1471 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE))
1472 return -1;
1474 uiOffset += MAX_RW_SIZE;
1475 uiNumBytes -= MAX_RW_SIZE;
1476 uiIndex += 4;
1477 } else if (uiNumBytes >= 4) {
1478 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
1479 if (uiData != pBuffer[uiIndex]) {
1480 /* re-write */
1481 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, false);
1482 mdelay(3);
1483 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
1484 if (uiData != pBuffer[uiIndex])
1485 return -1;
1487 uiOffset += 4;
1488 uiNumBytes -= 4;
1489 uiIndex++;
1490 } else {
1491 /* Handle the reads less than 4 bytes... */
1492 uiData = 0;
1493 memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(unsigned int)), uiNumBytes);
1494 BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4);
1496 if (memcmp(&uiData, &uiRdbk, uiNumBytes))
1497 return -1;
1499 uiNumBytes = 0;
1503 return 0;
1506 static VOID BcmSwapWord(unsigned int *ptr1)
1508 unsigned int tempval = (unsigned int)*ptr1;
1509 char *ptr2 = (char *)&tempval;
1510 char *ptr = (char *)ptr1;
1512 ptr[0] = ptr2[3];
1513 ptr[1] = ptr2[2];
1514 ptr[2] = ptr2[1];
1515 ptr[3] = ptr2[0];
1519 * Procedure: BeceemEEPROMWritePage
1521 * Description: Performs page write (16bytes) to the EEPROM
1523 * Arguments:
1524 * Adapter - ptr to Adapter object instance
1525 * uiData - Data to be written.
1526 * uiOffset - Offset of the EEPROM where data needs to be written to.
1527 * Returns:
1528 * OSAL_STATUS_CODE
1532 static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, unsigned int uiData[], unsigned int uiOffset)
1534 unsigned int uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
1535 unsigned int uiStatus = 0;
1536 UCHAR uiEpromStatus = 0;
1537 unsigned int value = 0;
1539 /* Flush the Write/Read/Cmd queues. */
1540 value = (EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH);
1541 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
1542 value = 0;
1543 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
1545 /* Clear the Empty/Avail/Full bits. After this it has been confirmed
1546 * that the bit was cleared by reading back the register. See NOTE below.
1547 * We also clear the Read queues as we do a EEPROM status register read
1548 * later.
1550 value = (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
1551 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
1553 /* Enable write */
1554 value = EEPROM_WRITE_ENABLE;
1555 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
1557 /* We can write back to back 8bits * 16 into the queue and as we have
1558 * checked for the queue to be empty we can write in a burst.
1561 value = uiData[0];
1562 BcmSwapWord(&value);
1563 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1565 value = uiData[1];
1566 BcmSwapWord(&value);
1567 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1569 value = uiData[2];
1570 BcmSwapWord(&value);
1571 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1573 value = uiData[3];
1574 BcmSwapWord(&value);
1575 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
1577 /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG
1578 * shows that we see 7 for the EEPROM data write. Which means that
1579 * queue got full, also space is available as well as the queue is empty.
1580 * This may happen in sequence.
1582 value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset;
1583 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
1585 /* Ideally we should loop here without tries and eventually succeed.
1586 * What we are checking if the previous write has completed, and this
1587 * may take time. We should wait till the Empty bit is set.
1589 uiStatus = 0;
1590 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
1591 while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) {
1592 uiRetries--;
1593 if (uiRetries == 0) {
1594 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY);
1595 return STATUS_FAILURE;
1598 if (!(uiRetries%RETRIES_PER_DELAY))
1599 udelay(1000);
1601 uiStatus = 0;
1602 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
1603 if (Adapter->device_removed == TRUE) {
1604 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop....");
1605 return -ENODEV;
1609 if (uiRetries != 0) {
1610 /* Clear the ones that are set - either, Empty/Full/Avail bits */
1611 value = (uiStatus & (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL));
1612 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
1615 /* Here we should check if the EEPROM status register is correct before
1616 * proceeding. Bit 0 in the EEPROM Status register should be 0 before
1617 * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy
1618 * with the previous write. Note also that issuing this read finally
1619 * means the previous write to the EEPROM has completed.
1621 uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
1622 uiEpromStatus = 0;
1623 while (uiRetries != 0) {
1624 uiEpromStatus = ReadEEPROMStatusRegister(Adapter);
1625 if (Adapter->device_removed == TRUE) {
1626 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
1627 return -ENODEV;
1629 if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) {
1630 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY - uiRetries));
1631 return STATUS_SUCCESS;
1633 uiRetries--;
1634 if (uiRetries == 0) {
1635 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);
1636 return STATUS_FAILURE;
1638 uiEpromStatus = 0;
1639 if (!(uiRetries%RETRIES_PER_DELAY))
1640 udelay(1000);
1643 return STATUS_SUCCESS;
1644 } /* BeceemEEPROMWritePage */
1647 * Procedure: BeceemEEPROMBulkWrite
1649 * Description: Performs write to the EEPROM
1651 * Arguments:
1652 * Adapter - ptr to Adapter object instance
1653 * pBuffer - Data to be written.
1654 * uiOffset - Offset of the EEPROM where data needs to be written to.
1655 * uiNumBytes - Number of bytes to be written.
1656 * bVerify - read verify flag.
1657 * Returns:
1658 * OSAL_STATUS_CODE
1662 int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter,
1663 PUCHAR pBuffer,
1664 unsigned int uiOffset,
1665 unsigned int uiNumBytes,
1666 bool bVerify)
1668 unsigned int uiBytesToCopy = uiNumBytes;
1669 /* unsigned int uiRdbk = 0; */
1670 unsigned int uiData[4] = {0};
1671 unsigned int uiIndex = 0;
1672 unsigned int uiTempOffset = 0;
1673 unsigned int uiExtraBytes = 0;
1674 /* PUINT puiBuffer = (PUINT)pBuffer;
1675 * int value;
1678 if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) {
1679 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
1680 uiExtraBytes = uiOffset - uiTempOffset;
1682 BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE);
1684 if (uiBytesToCopy >= (16 - uiExtraBytes)) {
1685 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes);
1687 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
1688 return STATUS_FAILURE;
1690 uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes);
1691 uiIndex += (MAX_RW_SIZE - uiExtraBytes);
1692 uiOffset += (MAX_RW_SIZE - uiExtraBytes);
1693 } else {
1694 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy);
1696 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
1697 return STATUS_FAILURE;
1699 uiIndex += uiBytesToCopy;
1700 uiOffset += uiBytesToCopy;
1701 uiBytesToCopy = 0;
1705 while (uiBytesToCopy) {
1706 if (Adapter->device_removed)
1707 return -1;
1709 if (uiBytesToCopy >= MAX_RW_SIZE) {
1710 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset))
1711 return STATUS_FAILURE;
1713 uiIndex += MAX_RW_SIZE;
1714 uiOffset += MAX_RW_SIZE;
1715 uiBytesToCopy -= MAX_RW_SIZE;
1716 } else {
1718 * To program non 16byte aligned data, read 16byte and then update.
1720 BeceemEEPROMBulkRead(Adapter, &uiData[0], uiOffset, 16);
1721 memcpy(&uiData[0], pBuffer + uiIndex, uiBytesToCopy);
1723 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiOffset))
1724 return STATUS_FAILURE;
1726 uiBytesToCopy = 0;
1730 return 0;
1734 * Procedure: BeceemNVMRead
1736 * Description: Reads n number of bytes from NVM.
1738 * Arguments:
1739 * Adapter - ptr to Adapter object instance
1740 * pBuffer - Buffer to store the data read from NVM
1741 * uiOffset - Offset of NVM from where data should be read
1742 * uiNumBytes - Number of bytes to be read from the NVM.
1744 * Returns:
1745 * OSAL_STATUS_SUCCESS - if NVM read is successful.
1746 * <FAILURE> - if failed.
1749 int BeceemNVMRead(struct bcm_mini_adapter *Adapter,
1750 PUINT pBuffer,
1751 unsigned int uiOffset,
1752 unsigned int uiNumBytes)
1754 int Status = 0;
1756 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
1757 unsigned int uiTemp = 0, value;
1758 #endif
1760 if (Adapter->eNVMType == NVM_FLASH) {
1761 if (Adapter->bFlashRawRead == false) {
1762 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
1763 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes);
1765 uiOffset = uiOffset + Adapter->ulFlashCalStart;
1768 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1769 Status = bcmflash_raw_read((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
1770 #else
1771 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1772 value = 0;
1773 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
1774 Status = BeceemFlashBulkRead(Adapter,
1775 pBuffer,
1776 uiOffset,
1777 uiNumBytes);
1778 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1779 #endif
1780 } else if (Adapter->eNVMType == NVM_EEPROM) {
1781 Status = BeceemEEPROMBulkRead(Adapter,
1782 pBuffer,
1783 uiOffset,
1784 uiNumBytes);
1785 } else {
1786 Status = -1;
1789 return Status;
1793 * Procedure: BeceemNVMWrite
1795 * Description: Writes n number of bytes to NVM.
1797 * Arguments:
1798 * Adapter - ptr to Adapter object instance
1799 * pBuffer - Buffer contains the data to be written.
1800 * uiOffset - Offset of NVM where data to be written to.
1801 * uiNumBytes - Number of bytes to be written..
1803 * Returns:
1804 * OSAL_STATUS_SUCCESS - if NVM write is successful.
1805 * <FAILURE> - if failed.
1808 int BeceemNVMWrite(struct bcm_mini_adapter *Adapter,
1809 PUINT pBuffer,
1810 unsigned int uiOffset,
1811 unsigned int uiNumBytes,
1812 bool bVerify)
1814 int Status = 0;
1815 unsigned int uiTemp = 0;
1816 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1817 unsigned int uiIndex = 0;
1819 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
1820 unsigned int value;
1821 #endif
1823 unsigned int uiFlashOffset = 0;
1825 if (Adapter->eNVMType == NVM_FLASH) {
1826 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
1827 Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify);
1828 else {
1829 uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;
1831 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
1832 Status = bcmflash_raw_write((uiFlashOffset / FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes);
1833 #else
1834 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1835 value = 0;
1836 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
1838 if (Adapter->bStatusWrite == TRUE)
1839 Status = BeceemFlashBulkWriteStatus(Adapter,
1840 pBuffer,
1841 uiFlashOffset,
1842 uiNumBytes ,
1843 bVerify);
1844 else
1846 Status = BeceemFlashBulkWrite(Adapter,
1847 pBuffer,
1848 uiFlashOffset,
1849 uiNumBytes,
1850 bVerify);
1851 #endif
1854 if (uiOffset >= EEPROM_CALPARAM_START) {
1855 uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
1856 while (uiNumBytes) {
1857 if (uiNumBytes > BUFFER_4K) {
1858 wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K);
1859 uiNumBytes -= BUFFER_4K;
1860 uiIndex += BUFFER_4K;
1861 } else {
1862 wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes);
1863 uiNumBytes = 0;
1864 break;
1867 } else {
1868 if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) {
1869 ULONG ulBytesTobeSkipped = 0;
1870 PUCHAR pcBuffer = (PUCHAR)pBuffer; /* char pointer to take care of odd byte cases. */
1871 uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
1872 ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
1873 uiOffset += (EEPROM_CALPARAM_START - uiOffset);
1874 while (uiNumBytes) {
1875 if (uiNumBytes > BUFFER_4K) {
1876 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K);
1877 uiNumBytes -= BUFFER_4K;
1878 uiIndex += BUFFER_4K;
1879 } else {
1880 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes);
1881 uiNumBytes = 0;
1882 break;
1887 /* restore the values. */
1888 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1889 } else if (Adapter->eNVMType == NVM_EEPROM) {
1890 Status = BeceemEEPROMBulkWrite(Adapter,
1891 (PUCHAR)pBuffer,
1892 uiOffset,
1893 uiNumBytes,
1894 bVerify);
1895 if (bVerify)
1896 Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes);
1897 } else {
1898 Status = -1;
1900 return Status;
1904 * Procedure: BcmUpdateSectorSize
1906 * Description: Updates the sector size to FLASH.
1908 * Arguments:
1909 * Adapter - ptr to Adapter object instance
1910 * uiSectorSize - sector size
1912 * Returns:
1913 * OSAL_STATUS_SUCCESS - if NVM write is successful.
1914 * <FAILURE> - if failed.
1917 int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, unsigned int uiSectorSize)
1919 int Status = -1;
1920 struct bcm_flash_cs_info sFlashCsInfo = {0};
1921 unsigned int uiTemp = 0;
1922 unsigned int uiSectorSig = 0;
1923 unsigned int uiCurrentSectorSize = 0;
1924 unsigned int value;
1926 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1927 value = 0;
1928 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
1931 * Before updating the sector size in the reserved area, check if already present.
1933 BeceemFlashBulkRead(Adapter, (PUINT)&sFlashCsInfo, Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo));
1934 uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
1935 uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);
1937 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
1938 if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) {
1939 if (uiSectorSize == uiCurrentSectorSize) {
1940 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash");
1941 Status = STATUS_SUCCESS;
1942 goto Restore;
1947 if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) {
1948 sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize);
1949 sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG);
1951 Status = BeceemFlashBulkWrite(Adapter,
1952 (PUINT)&sFlashCsInfo,
1953 Adapter->ulFlashControlSectionStart,
1954 sizeof(sFlashCsInfo),
1955 TRUE);
1958 Restore:
1959 /* restore the values. */
1960 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1962 return Status;
1966 * Procedure: BcmGetFlashSectorSize
1968 * Description: Finds the sector size of the FLASH.
1970 * Arguments:
1971 * Adapter - ptr to Adapter object instance
1973 * Returns:
1974 * unsigned int - sector size.
1978 static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize)
1980 unsigned int uiSectorSize = 0;
1981 unsigned int uiSectorSig = 0;
1983 if (Adapter->bSectorSizeOverride &&
1984 (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
1985 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) {
1986 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
1987 } else {
1988 uiSectorSig = FlashSectorSizeSig;
1990 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
1991 uiSectorSize = FlashSectorSize;
1993 * If the sector size stored in the FLASH makes sense then use it.
1995 if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) {
1996 Adapter->uiSectorSize = uiSectorSize;
1997 } else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
1998 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) {
1999 /* No valid size in FLASH, check if Config file has it. */
2000 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2001 } else {
2002 /* Init to Default, if none of the above works. */
2003 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2005 } else {
2006 if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2007 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
2008 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
2009 else
2010 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2014 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x\n", Adapter->uiSectorSize);
2016 return Adapter->uiSectorSize;
2020 * Procedure: BcmInitEEPROMQueues
2022 * Description: Initialization of EEPROM queues.
2024 * Arguments:
2025 * Adapter - ptr to Adapter object instance
2027 * Returns:
2028 * <OSAL_STATUS_CODE>
2031 static int BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter)
2033 unsigned int value = 0;
2034 /* CHIP Bug : Clear the Avail bits on the Read queue. The default
2035 * value on this register is supposed to be 0x00001102.
2036 * But we get 0x00001122.
2038 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n");
2039 value = EEPROM_READ_DATA_AVAIL;
2040 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
2042 /* Flush the all the EEPROM queues. */
2043 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n");
2044 value = EEPROM_ALL_QUEUE_FLUSH;
2045 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
2047 value = 0;
2048 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
2050 /* Read the EEPROM Status Register. Just to see, no real purpose. */
2051 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter));
2053 return STATUS_SUCCESS;
2054 } /* BcmInitEEPROMQueues() */
2057 * Procedure: BcmInitNVM
2059 * Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc.
2061 * Arguments:
2062 * Adapter - ptr to Adapter object instance
2064 * Returns:
2065 * <OSAL_STATUS_CODE>
2068 int BcmInitNVM(struct bcm_mini_adapter *ps_adapter)
2070 BcmValidateNvmType(ps_adapter);
2071 BcmInitEEPROMQueues(ps_adapter);
2073 if (ps_adapter->eNVMType == NVM_AUTODETECT) {
2074 ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
2075 if (ps_adapter->eNVMType == NVM_UNKNOWN)
2076 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
2077 } else if (ps_adapter->eNVMType == NVM_FLASH) {
2078 BcmGetFlashCSInfo(ps_adapter);
2081 BcmGetNvmSize(ps_adapter);
2083 return STATUS_SUCCESS;
2086 /* BcmGetNvmSize : set the EEPROM or flash size in Adapter.
2088 * Input Parameter:
2089 * Adapter data structure
2090 * Return Value :
2091 * 0. means success;
2094 static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter)
2096 if (Adapter->eNVMType == NVM_EEPROM)
2097 Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
2098 else if (Adapter->eNVMType == NVM_FLASH)
2099 Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
2101 return 0;
2105 * Procedure: BcmValidateNvm
2107 * Description: Validates the NVM Type option selected against the device
2109 * Arguments:
2110 * Adapter - ptr to Adapter object instance
2112 * Returns:
2113 * <VOID>
2116 static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter)
2119 * if forcing the FLASH through CFG file, we should ensure device really has a FLASH.
2120 * Accessing the FLASH address without the FLASH being present can cause hang/freeze etc.
2121 * So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice.
2124 if (Adapter->eNVMType == NVM_FLASH &&
2125 Adapter->chip_id < 0xBECE3300)
2126 Adapter->eNVMType = NVM_AUTODETECT;
2130 * Procedure: BcmReadFlashRDID
2132 * Description: Reads ID from Serial Flash
2134 * Arguments:
2135 * Adapter - ptr to Adapter object instance
2137 * Returns:
2138 * Flash ID
2141 static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter)
2143 ULONG ulRDID = 0;
2144 unsigned int value;
2147 * Read ID Instruction.
2149 value = (FLASH_CMD_READ_ID << 24);
2150 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
2152 /* Delay */
2153 udelay(10);
2156 * Read SPI READQ REG. The output will be WWXXYYZZ.
2157 * The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored.
2159 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID));
2161 return ulRDID >> 8;
2164 int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
2166 if (!psAdapter) {
2167 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
2168 return -EINVAL;
2170 psAdapter->psFlashCSInfo = kzalloc(sizeof(struct bcm_flash_cs_info), GFP_KERNEL);
2171 if (psAdapter->psFlashCSInfo == NULL) {
2172 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x");
2173 return -ENOMEM;
2176 psAdapter->psFlash2xCSInfo = kzalloc(sizeof(struct bcm_flash2x_cs_info), GFP_KERNEL);
2177 if (!psAdapter->psFlash2xCSInfo) {
2178 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x");
2179 kfree(psAdapter->psFlashCSInfo);
2180 return -ENOMEM;
2183 psAdapter->psFlash2xVendorInfo = kzalloc(sizeof(struct bcm_flash2x_vendor_info), GFP_KERNEL);
2184 if (!psAdapter->psFlash2xVendorInfo) {
2185 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x");
2186 kfree(psAdapter->psFlashCSInfo);
2187 kfree(psAdapter->psFlash2xCSInfo);
2188 return -ENOMEM;
2191 return STATUS_SUCCESS;
2194 int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
2196 if (!psAdapter) {
2197 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
2198 return -EINVAL;
2200 kfree(psAdapter->psFlashCSInfo);
2201 kfree(psAdapter->psFlash2xCSInfo);
2202 kfree(psAdapter->psFlash2xVendorInfo);
2203 return STATUS_SUCCESS;
2206 static int BcmDumpFlash2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo, struct bcm_mini_adapter *Adapter)
2208 unsigned int Index = 0;
2210 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************");
2211 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber));
2212 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2213 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion));
2214 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion));
2215 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion));
2216 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage));
2217 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware));
2218 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware));
2219 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage));
2220 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart));
2221 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd));
2222 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart));
2223 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd));
2224 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart));
2225 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData));
2226 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout));
2227 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature));
2228 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig));
2229 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize));
2230 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize));
2231 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize));
2232 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr));
2233 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize));
2234 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig));
2235 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout));
2236 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start));
2237 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End));
2238 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start));
2239 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End));
2240 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start));
2241 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End));
2242 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start));
2243 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End));
2244 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start));
2245 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End));
2246 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start));
2247 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End));
2248 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader));
2249 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start));
2250 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End));
2251 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start));
2252 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End));
2253 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start));
2254 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End));
2255 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start));
2256 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End));
2257 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :");
2259 for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++)
2260 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
2261 (psFlash2xCSInfo->SectorAccessBitMap[Index]));
2263 return STATUS_SUCCESS;
2266 static int ConvertEndianOf2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo)
2268 unsigned int Index = 0;
2270 psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
2271 psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion);
2272 /* psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); */
2273 psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
2274 psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
2275 psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
2276 psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
2277 psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware);
2278 psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage);
2279 psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart);
2280 psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
2281 psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart);
2282 psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
2283 psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
2284 psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData);
2285 psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout);
2286 psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature);
2287 psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig);
2288 psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize);
2289 psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize);
2290 psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize);
2291 psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr);
2292 psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize);
2293 psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig);
2294 psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout);
2295 psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start);
2296 psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End);
2297 psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start);
2298 psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End);
2299 psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start);
2300 psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End);
2301 psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start);
2302 psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End);
2303 psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start);
2304 psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End);
2305 psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start);
2306 psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End);
2307 psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader);
2308 psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
2309 psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End);
2310 psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
2311 psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End);
2312 psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
2313 psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End);
2314 psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
2315 psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End);
2317 for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++)
2318 psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
2320 return STATUS_SUCCESS;
2323 static int ConvertEndianOfCSStructure(struct bcm_flash_cs_info *psFlashCSInfo)
2325 /* unsigned int Index = 0; */
2326 psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber);
2327 psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion);
2328 psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion);
2329 /* won't convert according to old assumption */
2330 psFlashCSInfo->SCSIFirmwareVersion = (psFlashCSInfo->SCSIFirmwareVersion);
2331 psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage);
2332 psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware);
2333 psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware);
2334 psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage);
2335 psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2336 psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd);
2337 psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart);
2338 psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd);
2339 psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart);
2340 psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData);
2341 psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout);
2342 psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature);
2343 psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig);
2344 psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize);
2345 psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize);
2346 psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize);
2347 psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr);
2348 psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize);
2349 psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig);
2350 psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout);
2352 return STATUS_SUCCESS;
2355 static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
2357 return (Adapter->uiVendorExtnFlag &&
2358 (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
2359 (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS));
2362 static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter)
2364 B_UINT32 i = 0;
2365 unsigned int uiSizeSection = 0;
2367 Adapter->uiVendorExtnFlag = false;
2369 for (i = 0; i < TOTAL_SECTIONS; i++)
2370 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
2372 if (STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
2373 return;
2375 i = 0;
2376 while (i < TOTAL_SECTIONS) {
2377 if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) {
2378 i++;
2379 continue;
2382 Adapter->uiVendorExtnFlag = TRUE;
2383 uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
2384 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
2386 switch (i) {
2387 case DSD0:
2388 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
2389 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2390 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS;
2391 else
2392 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS;
2393 break;
2395 case DSD1:
2396 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
2397 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2398 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS;
2399 else
2400 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS;
2401 break;
2403 case DSD2:
2404 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) &&
2405 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart))
2406 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS;
2407 else
2408 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS;
2409 break;
2410 case VSA0:
2411 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2412 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS;
2413 else
2414 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS;
2415 break;
2417 case VSA1:
2418 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2419 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS;
2420 else
2421 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS;
2422 break;
2423 case VSA2:
2424 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)
2425 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS;
2426 else
2427 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS;
2428 break;
2430 default:
2431 break;
2433 i++;
2438 * Procedure: BcmGetFlashCSInfo
2440 * Description: Reads control structure and gets Cal section addresses.
2442 * Arguments:
2443 * Adapter - ptr to Adapter object instance
2445 * Returns:
2446 * <VOID>
2449 static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter)
2451 /* struct bcm_flash_cs_info sFlashCsInfo = {0}; */
2453 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2454 unsigned int value;
2455 #endif
2457 unsigned int uiFlashLayoutMajorVersion;
2458 Adapter->uiFlashLayoutMinorVersion = 0;
2459 Adapter->uiFlashLayoutMajorVersion = 0;
2460 Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
2462 Adapter->uiFlashBaseAdd = 0;
2463 Adapter->ulFlashCalStart = 0;
2464 memset(Adapter->psFlashCSInfo, 0 , sizeof(struct bcm_flash_cs_info));
2465 memset(Adapter->psFlash2xCSInfo, 0 , sizeof(struct bcm_flash2x_cs_info));
2467 if (!Adapter->bDDRInitDone) {
2468 value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
2469 wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
2472 /* Reading first 8 Bytes to get the Flash Layout
2473 * MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
2475 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8);
2477 Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
2478 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
2479 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); */
2480 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));
2482 if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) {
2483 uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2484 Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2485 } else {
2486 Adapter->uiFlashLayoutMinorVersion = 0;
2487 uiFlashLayoutMajorVersion = 0;
2490 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);
2492 if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) {
2493 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash_cs_info));
2494 ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
2495 Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2497 if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
2498 Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
2500 if ((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) &&
2501 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) &&
2502 (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) &&
2503 (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) {
2504 Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
2505 Adapter->fpFlashWrite = flashByteWrite;
2506 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2507 } else {
2508 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2509 Adapter->fpFlashWrite = flashWrite;
2510 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2513 BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
2514 (Adapter->psFlashCSInfo->FlashSectorSize));
2515 Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2516 } else {
2517 if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL,
2518 Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash2x_cs_info))) {
2519 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n");
2520 return STATUS_FAILURE;
2523 ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
2524 BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo, Adapter);
2525 if ((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) &&
2526 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) &&
2527 (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) &&
2528 (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) {
2529 Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
2530 Adapter->fpFlashWrite = flashByteWrite;
2531 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
2532 } else {
2533 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2534 Adapter->fpFlashWrite = flashWrite;
2535 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
2538 BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
2539 Adapter->psFlash2xCSInfo->FlashSectorSize);
2541 UpdateVendorInfo(Adapter);
2543 BcmGetActiveDSD(Adapter);
2544 BcmGetActiveISO(Adapter);
2545 Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2546 Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;
2549 * Concerns: what if CS sector size does not match with this sector size ???
2550 * what is the indication of AccessBitMap in CS in flash 2.x ????
2552 Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
2553 Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
2555 return STATUS_SUCCESS;
2559 * Procedure: BcmGetNvmType
2561 * Description: Finds the type of NVM used.
2563 * Arguments:
2564 * Adapter - ptr to Adapter object instance
2566 * Returns:
2567 * NVM_TYPE
2571 static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter)
2573 unsigned int uiData = 0;
2575 BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4);
2576 if (uiData == BECM)
2577 return NVM_EEPROM;
2580 * Read control struct and get cal addresses before accessing the flash
2582 BcmGetFlashCSInfo(Adapter);
2584 BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4);
2585 if (uiData == BECM)
2586 return NVM_FLASH;
2589 * even if there is no valid signature on EEPROM/FLASH find out if they really exist.
2590 * if exist select it.
2592 if (BcmGetEEPROMSize(Adapter))
2593 return NVM_EEPROM;
2595 /* TBD for Flash. */
2596 return NVM_UNKNOWN;
2600 * BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given
2601 * @Adapter : Drivers Private Data structure
2602 * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
2604 * Return value:-
2605 * On success it return the start offset of the provided section val
2606 * On Failure -returns STATUS_FAILURE
2609 int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
2612 * Considering all the section for which end offset can be calculated or directly given
2613 * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section
2614 * endoffset can't be calculated or given in CS Structure.
2617 int SectStartOffset = 0;
2619 SectStartOffset = INVALID_OFFSET;
2621 if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal))
2622 return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
2624 switch (eFlashSectionVal) {
2625 case ISO_IMAGE1:
2626 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
2627 (IsNonCDLessDevice(Adapter) == false))
2628 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
2629 break;
2630 case ISO_IMAGE2:
2631 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
2632 (IsNonCDLessDevice(Adapter) == false))
2633 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
2634 break;
2635 case DSD0:
2636 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
2637 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart);
2638 break;
2639 case DSD1:
2640 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
2641 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start);
2642 break;
2643 case DSD2:
2644 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
2645 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start);
2646 break;
2647 case VSA0:
2648 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
2649 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart);
2650 break;
2651 case VSA1:
2652 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
2653 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start);
2654 break;
2655 case VSA2:
2656 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
2657 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start);
2658 break;
2659 case SCSI:
2660 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
2661 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
2662 break;
2663 case CONTROL_SECTION:
2664 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
2665 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart);
2666 break;
2667 case ISO_IMAGE1_PART2:
2668 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS)
2669 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start);
2670 break;
2671 case ISO_IMAGE1_PART3:
2672 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS)
2673 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
2674 break;
2675 case ISO_IMAGE2_PART2:
2676 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS)
2677 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start);
2678 break;
2679 case ISO_IMAGE2_PART3:
2680 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS)
2681 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
2682 break;
2683 default:
2684 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
2685 SectStartOffset = INVALID_OFFSET;
2688 return SectStartOffset;
2692 * BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given
2693 * @Adapter : Drivers Private Data structure
2694 * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val
2696 * Return value:-
2697 * On success it return the end offset of the provided section val
2698 * On Failure -returns STATUS_FAILURE
2701 int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
2703 int SectEndOffset = 0;
2705 SectEndOffset = INVALID_OFFSET;
2706 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
2707 return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
2709 switch (eFlash2xSectionVal) {
2710 case ISO_IMAGE1:
2711 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) &&
2712 (IsNonCDLessDevice(Adapter) == false))
2713 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End);
2714 break;
2715 case ISO_IMAGE2:
2716 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) &&
2717 (IsNonCDLessDevice(Adapter) == false))
2718 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End);
2719 break;
2720 case DSD0:
2721 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS)
2722 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd);
2723 break;
2724 case DSD1:
2725 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS)
2726 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End);
2727 break;
2728 case DSD2:
2729 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS)
2730 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End);
2731 break;
2732 case VSA0:
2733 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS)
2734 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd);
2735 break;
2736 case VSA1:
2737 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS)
2738 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End);
2739 break;
2740 case VSA2:
2741 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS)
2742 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End);
2743 break;
2744 case SCSI:
2745 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
2746 SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) +
2747 (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware));
2748 break;
2749 case CONTROL_SECTION:
2750 /* Not Clear So Putting failure. confirm and fix it. */
2751 SectEndOffset = STATUS_FAILURE;
2752 break;
2753 case ISO_IMAGE1_PART2:
2754 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS)
2755 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End);
2756 break;
2757 case ISO_IMAGE1_PART3:
2758 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS)
2759 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End);
2760 break;
2761 case ISO_IMAGE2_PART2:
2762 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS)
2763 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End);
2764 break;
2765 case ISO_IMAGE2_PART3:
2766 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS)
2767 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End);
2768 break;
2769 default:
2770 SectEndOffset = INVALID_OFFSET;
2773 return SectEndOffset;
2777 * BcmFlash2xBulkRead:- Read API for Flash Map 2.x .
2778 * @Adapter :Driver Private Data Structure
2779 * @pBuffer : Buffer where data has to be put after reading
2780 * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val
2781 * @uiOffsetWithinSectionVal :- Offset with in provided section
2782 * @uiNumBytes : Number of Bytes for Read
2784 * Return value:-
2785 * return true on success and STATUS_FAILURE on fail.
2788 int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
2789 PUINT pBuffer,
2790 enum bcm_flash2x_section_val eFlash2xSectionVal,
2791 unsigned int uiOffsetWithinSectionVal,
2792 unsigned int uiNumBytes)
2794 int Status = STATUS_SUCCESS;
2795 int SectionStartOffset = 0;
2796 unsigned int uiAbsoluteOffset = 0;
2797 unsigned int uiTemp = 0, value = 0;
2799 if (!Adapter) {
2800 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
2801 return -EINVAL;
2803 if (Adapter->device_removed) {
2804 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
2805 return -ENODEV;
2808 /* NO_SECTION_VAL means absolute offset is given. */
2809 if (eFlash2xSectionVal == NO_SECTION_VAL)
2810 SectionStartOffset = 0;
2811 else
2812 SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
2814 if (SectionStartOffset == STATUS_FAILURE) {
2815 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash 2.x Map ", eFlash2xSectionVal);
2816 return -EINVAL;
2819 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
2820 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
2822 /* calculating the absolute offset from FLASH; */
2823 uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
2824 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2825 value = 0;
2826 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2827 Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes);
2828 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2829 if (Status) {
2830 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
2831 return Status;
2834 return Status;
2838 * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x.
2839 * @Adapter :Driver Private Data Structure
2840 * @pBuffer : Buffer From where data has to taken for writing
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 Write
2845 * Return value:-
2846 * return true on success and STATUS_FAILURE on fail.
2850 int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
2851 PUINT pBuffer,
2852 enum bcm_flash2x_section_val eFlash2xSectVal,
2853 unsigned int uiOffset,
2854 unsigned int uiNumBytes,
2855 unsigned int bVerify)
2857 int Status = STATUS_SUCCESS;
2858 unsigned int FlashSectValStartOffset = 0;
2859 unsigned int uiTemp = 0, value = 0;
2861 if (!Adapter) {
2862 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
2863 return -EINVAL;
2866 if (Adapter->device_removed) {
2867 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
2868 return -ENODEV;
2871 /* NO_SECTION_VAL means absolute offset is given. */
2872 if (eFlash2xSectVal == NO_SECTION_VAL)
2873 FlashSectValStartOffset = 0;
2874 else
2875 FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal);
2877 if (FlashSectValStartOffset == STATUS_FAILURE) {
2878 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash Map 2.x", eFlash2xSectVal);
2879 return -EINVAL;
2882 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal))
2883 return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify);
2885 /* calculating the absolute offset from FLASH; */
2886 uiOffset = uiOffset + FlashSectValStartOffset;
2888 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2889 value = 0;
2890 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2892 Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify);
2894 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2895 if (Status) {
2896 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
2897 return Status;
2900 return Status;
2904 * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR
2905 * @Adapter :-Drivers private Data Structure
2907 * Return Value:-
2908 * Return STATUS_SUCESS if get success in setting the right DSD else negative error code
2912 static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter)
2914 enum bcm_flash2x_section_val uiHighestPriDSD = 0;
2916 uiHighestPriDSD = getHighestPriDSD(Adapter);
2917 Adapter->eActiveDSD = uiHighestPriDSD;
2919 if (DSD0 == uiHighestPriDSD)
2920 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
2921 if (DSD1 == uiHighestPriDSD)
2922 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
2923 if (DSD2 == uiHighestPriDSD)
2924 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
2925 if (Adapter->eActiveDSD)
2926 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
2927 if (Adapter->eActiveDSD == 0) {
2928 /* if No DSD gets Active, Make Active the DSD with WR permission */
2929 if (IsSectionWritable(Adapter, DSD2)) {
2930 Adapter->eActiveDSD = DSD2;
2931 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
2932 } else if (IsSectionWritable(Adapter, DSD1)) {
2933 Adapter->eActiveDSD = DSD1;
2934 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
2935 } else if (IsSectionWritable(Adapter, DSD0)) {
2936 Adapter->eActiveDSD = DSD0;
2937 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
2941 return STATUS_SUCCESS;
2945 * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue
2946 * @Adapter : Driver private Data Structure
2948 * Return Value:-
2949 * Sucsess:- STATUS_SUCESS
2950 * Failure- : negative erro code
2954 static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter)
2956 int HighestPriISO = 0;
2958 HighestPriISO = getHighestPriISO(Adapter);
2960 Adapter->eActiveISO = HighestPriISO;
2961 if (Adapter->eActiveISO == ISO_IMAGE2)
2962 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
2963 else if (Adapter->eActiveISO == ISO_IMAGE1)
2964 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
2966 if (Adapter->eActiveISO)
2967 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO);
2969 return STATUS_SUCCESS;
2973 * IsOffsetWritable :- it will tell the access permission of the sector having passed offset
2974 * @Adapter : Drivers Private Data Structure
2975 * @uiOffset : Offset provided in the Flash
2977 * Return Value:-
2978 * Success:-TRUE , offset is writable
2979 * Failure:-false, offset is RO
2983 B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset)
2985 unsigned int uiSectorNum = 0;
2986 unsigned int uiWordOfSectorPermission = 0;
2987 unsigned int uiBitofSectorePermission = 0;
2988 B_UINT32 permissionBits = 0;
2990 uiSectorNum = uiOffset/Adapter->uiSectorSize;
2992 /* calculating the word having this Sector Access permission from SectorAccessBitMap Array */
2993 uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16];
2995 /* calculating the bit index inside the word for this sector */
2996 uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16);
2998 /* Setting Access permission */
2999 permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission);
3000 permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
3001 if (permissionBits == SECTOR_READWRITE_PERMISSION)
3002 return TRUE;
3003 else
3004 return false;
3007 static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap)
3009 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
3011 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************");
3012 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1);
3013 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2);
3014 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD0 :0X%x", psFlash2xBitMap->DSD0);
3015 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD1 :0X%x", psFlash2xBitMap->DSD1);
3016 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD2 :0X%x", psFlash2xBitMap->DSD2);
3017 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA0 :0X%x", psFlash2xBitMap->VSA0);
3018 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA1 :0X%x", psFlash2xBitMap->VSA1);
3019 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA2 :0X%x", psFlash2xBitMap->VSA2);
3020 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSI :0X%x", psFlash2xBitMap->SCSI);
3021 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION);
3023 return STATUS_SUCCESS;
3027 * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash
3028 * 8bit has been assigned to every section.
3029 * bit[0] :Section present or not
3030 * bit[1] :section is valid or not
3031 * bit[2] : Secton is read only or has write permission too.
3032 * bit[3] : Active Section -
3033 * bit[7...4] = Reserved .
3035 * @Adapter:-Driver private Data Structure
3037 * Return value:-
3038 * Success:- STATUS_SUCESS
3039 * Failure:- negative error code
3042 int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap)
3044 struct bcm_flash2x_cs_info *psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
3045 enum bcm_flash2x_section_val uiHighestPriDSD = 0;
3046 enum bcm_flash2x_section_val uiHighestPriISO = 0;
3047 bool SetActiveDSDDone = false;
3048 bool SetActiveISODone = false;
3050 /* For 1.x map all the section except DSD0 will be shown as not present
3051 * This part will be used by calibration tool to detect the number of DSD present in Flash.
3053 if (IsFlash2x(Adapter) == false) {
3054 psFlash2xBitMap->ISO_IMAGE2 = 0;
3055 psFlash2xBitMap->ISO_IMAGE1 = 0;
3056 psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */
3057 psFlash2xBitMap->DSD1 = 0;
3058 psFlash2xBitMap->DSD2 = 0;
3059 psFlash2xBitMap->VSA0 = 0;
3060 psFlash2xBitMap->VSA1 = 0;
3061 psFlash2xBitMap->VSA2 = 0;
3062 psFlash2xBitMap->CONTROL_SECTION = 0;
3063 psFlash2xBitMap->SCSI = 0;
3064 psFlash2xBitMap->Reserved0 = 0;
3065 psFlash2xBitMap->Reserved1 = 0;
3066 psFlash2xBitMap->Reserved2 = 0;
3068 return STATUS_SUCCESS;
3071 uiHighestPriDSD = getHighestPriDSD(Adapter);
3072 uiHighestPriISO = getHighestPriISO(Adapter);
3075 * IS0 IMAGE 2
3077 if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) {
3078 /* Setting the 0th Bit representing the Section is present or not. */
3079 psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
3081 if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER)
3082 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
3084 /* Calculation for extrating the Access permission */
3085 if (IsSectionWritable(Adapter, ISO_IMAGE2) == false)
3086 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
3088 if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE2) {
3089 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT;
3090 SetActiveISODone = TRUE;
3095 * IS0 IMAGE 1
3097 if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) {
3098 /* Setting the 0th Bit representing the Section is present or not. */
3099 psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
3101 if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
3102 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
3104 /* Calculation for extrating the Access permission */
3105 if (IsSectionWritable(Adapter, ISO_IMAGE1) == false)
3106 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
3108 if (SetActiveISODone == false && uiHighestPriISO == ISO_IMAGE1) {
3109 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT;
3110 SetActiveISODone = TRUE;
3115 * DSD2
3117 if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) {
3118 /* Setting the 0th Bit representing the Section is present or not. */
3119 psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
3121 if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER)
3122 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
3124 /* Calculation for extrating the Access permission */
3125 if (IsSectionWritable(Adapter, DSD2) == false) {
3126 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
3127 } else {
3128 /* Means section is writable */
3129 if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD2)) {
3130 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT;
3131 SetActiveDSDDone = TRUE;
3137 * DSD 1
3139 if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) {
3140 /* Setting the 0th Bit representing the Section is present or not. */
3141 psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
3143 if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER)
3144 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
3146 /* Calculation for extrating the Access permission */
3147 if (IsSectionWritable(Adapter, DSD1) == false) {
3148 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
3149 } else {
3150 /* Means section is writable */
3151 if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD1)) {
3152 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT;
3153 SetActiveDSDDone = TRUE;
3159 * For DSD 0
3161 if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) {
3162 /* Setting the 0th Bit representing the Section is present or not. */
3163 psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
3165 if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER)
3166 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
3168 /* Setting Access permission */
3169 if (IsSectionWritable(Adapter, DSD0) == false) {
3170 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
3171 } else {
3172 /* Means section is writable */
3173 if ((SetActiveDSDDone == false) && (uiHighestPriDSD == DSD0)) {
3174 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT;
3175 SetActiveDSDDone = TRUE;
3181 * VSA 0
3183 if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) {
3184 /* Setting the 0th Bit representing the Section is present or not. */
3185 psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
3187 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3188 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
3190 /* Calculation for extrating the Access permission */
3191 if (IsSectionWritable(Adapter, VSA0) == false)
3192 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO;
3194 /* By Default section is Active */
3195 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT;
3199 * VSA 1
3201 if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) {
3202 /* Setting the 0th Bit representing the Section is present or not. */
3203 psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
3205 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3206 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID;
3208 /* Checking For Access permission */
3209 if (IsSectionWritable(Adapter, VSA1) == false)
3210 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
3212 /* By Default section is Active */
3213 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT;
3217 * VSA 2
3219 if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) {
3220 /* Setting the 0th Bit representing the Section is present or not. */
3221 psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
3223 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3224 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
3226 /* Checking For Access permission */
3227 if (IsSectionWritable(Adapter, VSA2) == false)
3228 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
3230 /* By Default section is Active */
3231 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT;
3235 * SCSI Section
3237 if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) {
3238 /* Setting the 0th Bit representing the Section is present or not. */
3239 psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
3241 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3242 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID;
3244 /* Checking For Access permission */
3245 if (IsSectionWritable(Adapter, SCSI) == false)
3246 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
3248 /* By Default section is Active */
3249 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT;
3253 * Control Section
3255 if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) {
3256 /* Setting the 0th Bit representing the Section is present or not. */
3257 psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
3259 /* Setting the Access Bit. Map is not defined hece setting it always valid */
3260 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
3262 /* Checking For Access permission */
3263 if (IsSectionWritable(Adapter, CONTROL_SECTION) == false)
3264 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
3266 /* By Default section is Active */
3267 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT;
3271 * For Reserved Sections
3273 psFlash2xBitMap->Reserved0 = 0;
3274 psFlash2xBitMap->Reserved0 = 0;
3275 psFlash2xBitMap->Reserved0 = 0;
3276 BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
3278 return STATUS_SUCCESS;
3282 * BcmSetActiveSection :- Set Active section is used to make priority field highest over other
3283 * section of same type.
3285 * @Adapater :- Bcm Driver Private Data Structure
3286 * @eFlash2xSectionVal :- Flash section val whose priority has to be made highest.
3288 * Return Value:- Make the priorit highest else return erorr code
3292 int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal)
3294 unsigned int SectImagePriority = 0;
3295 int Status = STATUS_SUCCESS;
3297 /* struct bcm_dsd_header sDSD = {0};
3298 * struct bcm_iso_header sISO = {0};
3300 int HighestPriDSD = 0;
3301 int HighestPriISO = 0;
3303 Status = IsSectionWritable(Adapter, eFlash2xSectVal);
3304 if (Status != TRUE) {
3305 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal);
3306 return STATUS_FAILURE;
3309 Adapter->bHeaderChangeAllowed = TRUE;
3310 switch (eFlash2xSectVal) {
3311 case ISO_IMAGE1:
3312 case ISO_IMAGE2:
3313 if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) {
3314 HighestPriISO = getHighestPriISO(Adapter);
3316 if (HighestPriISO == eFlash2xSectVal) {
3317 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
3318 Status = STATUS_SUCCESS;
3319 break;
3322 SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1;
3324 if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) {
3325 /* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF.
3326 * We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO
3327 * by user
3329 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
3330 SectImagePriority = htonl(0x1);
3331 Status = BcmFlash2xBulkWrite(Adapter,
3332 &SectImagePriority,
3333 HighestPriISO,
3334 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
3335 SIGNATURE_SIZE,
3336 TRUE);
3337 if (Status) {
3338 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3339 Status = STATUS_FAILURE;
3340 break;
3343 HighestPriISO = getHighestPriISO(Adapter);
3345 if (HighestPriISO == eFlash2xSectVal) {
3346 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal);
3347 Status = STATUS_SUCCESS;
3348 break;
3351 SectImagePriority = 2;
3354 SectImagePriority = htonl(SectImagePriority);
3356 Status = BcmFlash2xBulkWrite(Adapter,
3357 &SectImagePriority,
3358 eFlash2xSectVal,
3359 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
3360 SIGNATURE_SIZE,
3361 TRUE);
3362 if (Status) {
3363 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3364 break;
3366 } else {
3367 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3368 Status = STATUS_FAILURE;
3369 break;
3371 break;
3372 case DSD0:
3373 case DSD1:
3374 case DSD2:
3375 if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) {
3376 HighestPriDSD = getHighestPriDSD(Adapter);
3377 if ((HighestPriDSD == eFlash2xSectVal)) {
3378 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal);
3379 Status = STATUS_SUCCESS;
3380 break;
3383 SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1;
3384 if (SectImagePriority <= 0) {
3385 /* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF.
3386 * We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD
3387 * by user
3389 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal);
3390 SectImagePriority = htonl(0x1);
3392 Status = BcmFlash2xBulkWrite(Adapter,
3393 &SectImagePriority,
3394 HighestPriDSD,
3395 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
3396 SIGNATURE_SIZE,
3397 TRUE);
3398 if (Status) {
3399 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3400 break;
3403 HighestPriDSD = getHighestPriDSD(Adapter);
3405 if ((HighestPriDSD == eFlash2xSectVal)) {
3406 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal);
3407 Status = STATUS_SUCCESS;
3408 break;
3411 SectImagePriority = htonl(0x2);
3412 Status = BcmFlash2xBulkWrite(Adapter,
3413 &SectImagePriority,
3414 HighestPriDSD,
3415 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
3416 SIGNATURE_SIZE,
3417 TRUE);
3418 if (Status) {
3419 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3420 break;
3423 HighestPriDSD = getHighestPriDSD(Adapter);
3424 if ((HighestPriDSD == eFlash2xSectVal)) {
3425 Status = STATUS_SUCCESS;
3426 break;
3429 SectImagePriority = 3;
3431 SectImagePriority = htonl(SectImagePriority);
3432 Status = BcmFlash2xBulkWrite(Adapter,
3433 &SectImagePriority,
3434 eFlash2xSectVal,
3435 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
3436 SIGNATURE_SIZE,
3437 TRUE);
3438 if (Status) {
3439 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3440 Status = STATUS_FAILURE;
3441 break;
3443 } else {
3444 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
3445 Status = STATUS_FAILURE;
3446 break;
3448 break;
3449 case VSA0:
3450 case VSA1:
3451 case VSA2:
3452 /* Has to be decided */
3453 break;
3454 default:
3455 Status = STATUS_FAILURE;
3456 break;
3459 Adapter->bHeaderChangeAllowed = false;
3460 return Status;
3464 * BcmCopyISO - Used only for copying the ISO section
3465 * @Adapater :- Bcm Driver Private Data Structure
3466 * @sCopySectStrut :- Section copy structure
3468 * Return value:- SUCCESS if copies successfully else negative error code
3472 int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut)
3474 PCHAR Buff = NULL;
3475 enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0;
3476 unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
3477 unsigned int uiTotalDataToCopy = 0;
3478 bool IsThisHeaderSector = false;
3479 unsigned int sigOffset = 0;
3480 unsigned int ISOLength = 0;
3481 unsigned int Status = STATUS_SUCCESS;
3482 unsigned int SigBuff[MAX_RW_SIZE];
3483 unsigned int i = 0;
3485 if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) {
3486 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3487 return STATUS_FAILURE;
3490 Status = BcmFlash2xBulkRead(Adapter,
3491 &ISOLength,
3492 sCopySectStrut.SrcSection,
3493 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize),
3495 if (Status) {
3496 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
3497 return Status;
3500 ISOLength = htonl(ISOLength);
3501 if (ISOLength % Adapter->uiSectorSize)
3502 ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize);
3504 sigOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber);
3506 Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
3508 if (!Buff) {
3509 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size");
3510 return -ENOMEM;
3513 if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) {
3514 eISOReadPart = ISO_IMAGE1;
3515 eISOWritePart = ISO_IMAGE2;
3516 uiReadOffsetWithinPart = 0;
3517 uiWriteOffsetWithinPart = 0;
3519 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
3520 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
3521 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
3522 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
3523 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
3524 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3526 if (uiTotalDataToCopy < ISOLength) {
3527 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3528 Status = STATUS_FAILURE;
3529 goto out;
3532 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
3533 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
3534 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
3535 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
3536 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
3537 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3539 if (uiTotalDataToCopy < ISOLength) {
3540 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
3541 Status = STATUS_FAILURE;
3542 goto out;
3545 uiTotalDataToCopy = ISOLength;
3547 CorruptISOSig(Adapter, ISO_IMAGE2);
3548 while (uiTotalDataToCopy) {
3549 if (uiTotalDataToCopy == Adapter->uiSectorSize) {
3550 /* Setting for write of first sector. First sector is assumed to be written in last */
3551 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
3552 eISOReadPart = ISO_IMAGE1;
3553 uiReadOffsetWithinPart = 0;
3554 eISOWritePart = ISO_IMAGE2;
3555 uiWriteOffsetWithinPart = 0;
3556 IsThisHeaderSector = TRUE;
3557 } else {
3558 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3559 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
3561 if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
3562 eISOReadPart = ISO_IMAGE1_PART2;
3563 uiReadOffsetWithinPart = 0;
3566 if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
3567 eISOReadPart = ISO_IMAGE1_PART3;
3568 uiReadOffsetWithinPart = 0;
3571 if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
3572 eISOWritePart = ISO_IMAGE2_PART2;
3573 uiWriteOffsetWithinPart = 0;
3576 if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
3577 eISOWritePart = ISO_IMAGE2_PART3;
3578 uiWriteOffsetWithinPart = 0;
3582 Status = BcmFlash2xBulkRead(Adapter,
3583 (PUINT)Buff,
3584 eISOReadPart,
3585 uiReadOffsetWithinPart,
3586 Adapter->uiSectorSize);
3587 if (Status) {
3588 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
3589 break;
3592 if (IsThisHeaderSector == TRUE) {
3593 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
3594 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
3596 for (i = 0; i < MAX_RW_SIZE; i++)
3597 *(Buff + sigOffset + i) = 0xFF;
3599 Adapter->bHeaderChangeAllowed = TRUE;
3600 Status = BcmFlash2xBulkWrite(Adapter,
3601 (PUINT)Buff,
3602 eISOWritePart,
3603 uiWriteOffsetWithinPart,
3604 Adapter->uiSectorSize,
3605 TRUE);
3606 if (Status) {
3607 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
3608 break;
3611 Adapter->bHeaderChangeAllowed = false;
3612 if (IsThisHeaderSector == TRUE) {
3613 WriteToFlashWithoutSectorErase(Adapter,
3614 SigBuff,
3615 eISOWritePart,
3616 sigOffset,
3617 MAX_RW_SIZE);
3618 IsThisHeaderSector = false;
3620 /* subtracting the written Data */
3621 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
3625 if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) {
3626 eISOReadPart = ISO_IMAGE2;
3627 eISOWritePart = ISO_IMAGE1;
3628 uiReadOffsetWithinPart = 0;
3629 uiWriteOffsetWithinPart = 0;
3631 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) -
3632 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) +
3633 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) -
3634 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) +
3635 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) -
3636 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start);
3638 if (uiTotalDataToCopy < ISOLength) {
3639 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
3640 Status = STATUS_FAILURE;
3641 goto out;
3644 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) -
3645 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) +
3646 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) -
3647 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) +
3648 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) -
3649 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start);
3651 if (uiTotalDataToCopy < ISOLength) {
3652 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
3653 Status = STATUS_FAILURE;
3654 goto out;
3657 uiTotalDataToCopy = ISOLength;
3659 CorruptISOSig(Adapter, ISO_IMAGE1);
3661 while (uiTotalDataToCopy) {
3662 if (uiTotalDataToCopy == Adapter->uiSectorSize) {
3663 /* Setting for write of first sector. First sector is assumed to be written in last */
3664 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
3665 eISOReadPart = ISO_IMAGE2;
3666 uiReadOffsetWithinPart = 0;
3667 eISOWritePart = ISO_IMAGE1;
3668 uiWriteOffsetWithinPart = 0;
3669 IsThisHeaderSector = TRUE;
3670 } else {
3671 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3672 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
3674 if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
3675 eISOReadPart = ISO_IMAGE2_PART2;
3676 uiReadOffsetWithinPart = 0;
3679 if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
3680 eISOReadPart = ISO_IMAGE2_PART3;
3681 uiReadOffsetWithinPart = 0;
3684 if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
3685 eISOWritePart = ISO_IMAGE1_PART2;
3686 uiWriteOffsetWithinPart = 0;
3689 if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
3690 eISOWritePart = ISO_IMAGE1_PART3;
3691 uiWriteOffsetWithinPart = 0;
3695 Status = BcmFlash2xBulkRead(Adapter,
3696 (PUINT)Buff,
3697 eISOReadPart,
3698 uiReadOffsetWithinPart,
3699 Adapter->uiSectorSize);
3700 if (Status) {
3701 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
3702 break;
3705 if (IsThisHeaderSector == TRUE) {
3706 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */
3707 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
3709 for (i = 0; i < MAX_RW_SIZE; i++)
3710 *(Buff + sigOffset + i) = 0xFF;
3712 Adapter->bHeaderChangeAllowed = TRUE;
3713 Status = BcmFlash2xBulkWrite(Adapter,
3714 (PUINT)Buff,
3715 eISOWritePart,
3716 uiWriteOffsetWithinPart,
3717 Adapter->uiSectorSize,
3718 TRUE);
3719 if (Status) {
3720 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
3721 break;
3724 Adapter->bHeaderChangeAllowed = false;
3725 if (IsThisHeaderSector == TRUE) {
3726 WriteToFlashWithoutSectorErase(Adapter,
3727 SigBuff,
3728 eISOWritePart,
3729 sigOffset,
3730 MAX_RW_SIZE);
3732 IsThisHeaderSector = false;
3735 /* subtracting the written Data */
3736 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
3739 out:
3740 kfree(Buff);
3742 return Status;
3746 * BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section.
3747 * It will corrupt the sig, if Section is writable, by making first bytes as zero.
3748 * @Adapater :- Bcm Driver Private Data Structure
3749 * @eFlash2xSectionVal :- Flash section val which has header
3751 * Return Value :-
3752 * Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
3753 * Failure :-Return negative error code
3756 int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
3758 int Status = STATUS_SUCCESS;
3760 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal);
3762 if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) {
3763 Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
3764 } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) {
3765 Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
3766 } else {
3767 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal);
3768 return STATUS_SUCCESS;
3770 return Status;
3774 *BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has
3775 * header and Write Permission.
3776 * @Adapater :- Bcm Driver Private Data Structure
3777 * @eFlashSectionVal :- Flash section val which has header
3779 * Return Value :-
3780 * Success :- If Section is present and writable write the sig and return STATUS_SUCCESS
3781 * Failure :-Return negative error code
3784 int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal)
3786 unsigned int uiSignature = 0;
3787 unsigned int uiOffset = 0;
3789 /* struct bcm_dsd_header dsdHeader = {0}; */
3790 if (Adapter->bSigCorrupted == false) {
3791 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n");
3792 return STATUS_SUCCESS;
3795 if (Adapter->bAllDSDWriteAllow == false) {
3796 if (IsSectionWritable(Adapter, eFlashSectionVal) == false) {
3797 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature");
3798 return SECTOR_IS_NOT_WRITABLE;
3802 if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) {
3803 uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER);
3804 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader;
3806 uiOffset += FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber);
3808 if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
3809 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig");
3810 return STATUS_FAILURE;
3812 } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) {
3813 uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
3814 /* uiOffset = 0; */
3815 uiOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber);
3816 if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
3817 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig");
3818 return STATUS_FAILURE;
3820 } else {
3821 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
3822 return STATUS_FAILURE;
3825 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature");
3827 Adapter->bHeaderChangeAllowed = TRUE;
3828 Adapter->bSigCorrupted = false;
3829 BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE);
3830 Adapter->bHeaderChangeAllowed = false;
3832 return STATUS_SUCCESS;
3836 * validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write.
3837 * if requested Bytes goes beyond the Requested section, it reports error.
3838 * @Adapater :- Bcm Driver Private Data Structure
3839 * @psFlash2xReadWrite :-Flash2x Read/write structure pointer
3841 * Return values:-Return TRUE is request is valid else false.
3844 int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite)
3846 unsigned int uiNumOfBytes = 0;
3847 unsigned int uiSectStartOffset = 0;
3848 unsigned int uiSectEndOffset = 0;
3850 uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
3852 if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) {
3853 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exist in Flash", psFlash2xReadWrite->Section);
3854 return false;
3856 uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section);
3857 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section);
3858 if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) {
3859 if (psFlash2xReadWrite->Section == ISO_IMAGE1) {
3860 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) -
3861 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) +
3862 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) -
3863 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) +
3864 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) -
3865 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3);
3866 } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) {
3867 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) -
3868 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) +
3869 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) -
3870 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART2) +
3871 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART3) -
3872 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3);
3875 /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset
3876 * it should be added in startoffset. so that check done in last of this function can be valued.
3878 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset;
3880 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset);
3881 } else
3882 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section);
3884 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset);
3886 /* psFlash2xReadWrite->offset and uiNumOfBytes are user controlled and can lead to integer overflows */
3887 if (psFlash2xReadWrite->offset > uiSectEndOffset) {
3888 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
3889 return false;
3891 if (uiNumOfBytes > uiSectEndOffset) {
3892 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
3893 return false;
3895 /* Checking the boundary condition */
3896 if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
3897 return TRUE;
3898 else {
3899 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
3900 return false;
3905 * IsFlash2x :- check for Flash 2.x
3906 * Adapater :- Bcm Driver Private Data Structure
3908 * Return value:-
3909 * return TRUE if flah2.x of hgher version else return false.
3912 int IsFlash2x(struct bcm_mini_adapter *Adapter)
3914 if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
3915 return TRUE;
3916 else
3917 return false;
3921 * GetFlashBaseAddr :- Calculate the Flash Base address
3922 * @Adapater :- Bcm Driver Private Data Structure
3924 * Return Value:-
3925 * Success :- Base Address of the Flash
3928 static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
3930 unsigned int uiBaseAddr = 0;
3932 if (Adapter->bDDRInitDone) {
3934 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3935 * In case of Raw Read... use the default value
3937 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) &&
3938 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
3939 uiBaseAddr = Adapter->uiFlashBaseAdd;
3940 else
3941 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
3942 } else {
3944 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3945 * In case of Raw Read... use the default value
3947 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == false) &&
3948 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
3949 uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
3950 else
3951 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
3954 return uiBaseAddr;
3958 * BcmCopySection :- This API is used to copy the One section in another. Both section should
3959 * be contiuous and of same size. Hence this Will not be applicabe to copy ISO.
3961 * @Adapater :- Bcm Driver Private Data Structure
3962 * @SrcSection :- Source section From where data has to be copied
3963 * @DstSection :- Destination section to which data has to be copied
3964 * @offset :- Offset from/to where data has to be copied from one section to another.
3965 * @numOfBytes :- number of byes that has to be copyed from one section to another at given offset.
3966 * in case of numofBytes equal zero complete section will be copied.
3967 * Return Values-
3968 * Success : Return STATUS_SUCCESS
3969 * Faillure :- return negative error code
3972 int BcmCopySection(struct bcm_mini_adapter *Adapter,
3973 enum bcm_flash2x_section_val SrcSection,
3974 enum bcm_flash2x_section_val DstSection,
3975 unsigned int offset,
3976 unsigned int numOfBytes)
3978 unsigned int BuffSize = 0;
3979 unsigned int BytesToBeCopied = 0;
3980 PUCHAR pBuff = NULL;
3981 int Status = STATUS_SUCCESS;
3983 if (SrcSection == DstSection) {
3984 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again");
3985 return -EINVAL;
3988 if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) {
3989 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection");
3990 return -EINVAL;
3993 if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) {
3994 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection");
3995 return -EINVAL;
3998 /* if offset zero means have to copy complete secton */
3999 if (numOfBytes == 0) {
4000 numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection)
4001 - BcmGetSectionValStartOffset(Adapter, SrcSection);
4003 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes);
4006 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection)
4007 - BcmGetSectionValStartOffset(Adapter, SrcSection)) {
4008 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n",
4009 offset, numOfBytes);
4010 return -EINVAL;
4013 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection)
4014 - BcmGetSectionValStartOffset(Adapter, DstSection)) {
4015 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n",
4016 offset, numOfBytes);
4017 return -EINVAL;
4020 if (numOfBytes > Adapter->uiSectorSize)
4021 BuffSize = Adapter->uiSectorSize;
4022 else
4023 BuffSize = numOfBytes;
4025 pBuff = kzalloc(BuffSize, GFP_KERNEL);
4026 if (!pBuff) {
4027 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. ");
4028 return -ENOMEM;
4031 BytesToBeCopied = Adapter->uiSectorSize;
4032 if (offset % Adapter->uiSectorSize)
4033 BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
4034 if (BytesToBeCopied > numOfBytes)
4035 BytesToBeCopied = numOfBytes;
4037 Adapter->bHeaderChangeAllowed = TRUE;
4039 do {
4040 Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied);
4041 if (Status) {
4042 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied);
4043 break;
4045 Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, false);
4046 if (Status) {
4047 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied);
4048 break;
4050 offset = offset + BytesToBeCopied;
4051 numOfBytes = numOfBytes - BytesToBeCopied;
4052 if (numOfBytes) {
4053 if (numOfBytes > Adapter->uiSectorSize)
4054 BytesToBeCopied = Adapter->uiSectorSize;
4055 else
4056 BytesToBeCopied = numOfBytes;
4058 } while (numOfBytes > 0);
4060 kfree(pBuff);
4061 Adapter->bHeaderChangeAllowed = false;
4063 return Status;
4067 * SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write
4068 * @Adapater :- Bcm Driver Private Data Structure
4069 * @pBuff :- Data buffer that has to be written in sector having the header map.
4070 * @uiOffset :- Flash offset that has to be written.
4072 * Return value :-
4073 * Success :- On success return STATUS_SUCCESS
4074 * Faillure :- Return negative error code
4077 int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset)
4079 unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0;
4080 bool bHasHeader = false;
4081 PUCHAR pTempBuff = NULL;
4082 unsigned int uiSectAlignAddr = 0;
4083 unsigned int sig = 0;
4085 /* making the offset sector aligned */
4086 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4088 if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) ||
4089 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) ||
4090 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) {
4091 /* offset from the sector boundary having the header map */
4092 offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
4093 HeaderSizeToProtect = sizeof(struct bcm_dsd_header);
4094 bHasHeader = TRUE;
4097 if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) ||
4098 uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) {
4099 offsetToProtect = 0;
4100 HeaderSizeToProtect = sizeof(struct bcm_iso_header);
4101 bHasHeader = TRUE;
4103 /* If Header is present overwrite passed buffer with this */
4104 if (bHasHeader && (Adapter->bHeaderChangeAllowed == false)) {
4105 pTempBuff = kzalloc(HeaderSizeToProtect, GFP_KERNEL);
4106 if (!pTempBuff) {
4107 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed");
4108 return -ENOMEM;
4110 /* Read header */
4111 BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect);
4112 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect);
4113 /* Replace Buffer content with Header */
4114 memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect);
4116 kfree(pTempBuff);
4118 if (bHasHeader && Adapter->bSigCorrupted) {
4119 sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber)));
4120 sig = ntohl(sig);
4121 if ((sig & 0xFF000000) != CORRUPTED_PATTERN) {
4122 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore");
4123 Adapter->bSigCorrupted = false;
4124 return STATUS_SUCCESS;
4126 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig);
4127 *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER);
4128 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only");
4129 Adapter->bSigCorrupted = false;
4132 return STATUS_SUCCESS;
4136 * BcmDoChipSelect : This will selcet the appropriate chip for writing.
4137 * @Adapater :- Bcm Driver Private Data Structure
4139 * OutPut:-
4140 * Select the Appropriate chip and retrn status Success
4142 static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset)
4144 unsigned int FlashConfig = 0;
4145 int ChipNum = 0;
4146 unsigned int GPIOConfig = 0;
4147 unsigned int PartNum = 0;
4149 ChipNum = offset / FLASH_PART_SIZE;
4152 * Chip Select mapping to enable flash0.
4153 * To select flash 0, we have to OR with (0<<12).
4154 * ORing 0 will have no impact so not doing that part.
4155 * In future if Chip select value changes from 0 to non zero,
4156 * That needs be taken care with backward comaptibility. No worries for now.
4160 * SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured
4161 * if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken)
4162 * Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from
4163 * power down modes (Idle mode/shutdown mode), the values in the register will be different.
4166 if (Adapter->SelectedChip == ChipNum)
4167 return STATUS_SUCCESS;
4169 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); */
4170 Adapter->SelectedChip = ChipNum;
4172 /* bit[13..12] will select the appropriate chip */
4173 rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4174 rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4176 switch (ChipNum) {
4177 case 0:
4178 PartNum = 0;
4179 break;
4180 case 1:
4181 PartNum = 3;
4182 GPIOConfig |= (0x4 << CHIP_SELECT_BIT12);
4183 break;
4184 case 2:
4185 PartNum = 1;
4186 GPIOConfig |= (0x1 << CHIP_SELECT_BIT12);
4187 break;
4188 case 3:
4189 PartNum = 2;
4190 GPIOConfig |= (0x2 << CHIP_SELECT_BIT12);
4191 break;
4194 /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
4195 * nothing to do... can return immediately.
4196 * ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG.
4197 * Even if the chip goes to low power mode, it should wake with values in each register in sync with each other.
4198 * These values are not written by host other than during CHIP_SELECT.
4200 if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
4201 return STATUS_SUCCESS;
4203 /* clearing the bit[13..12] */
4204 FlashConfig &= 0xFFFFCFFF;
4205 FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); /* 00 */
4207 wrmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
4208 udelay(100);
4210 wrmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4211 udelay(100);
4213 return STATUS_SUCCESS;
4216 int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
4218 unsigned int uiDSDsig = 0;
4219 /* unsigned int sigoffsetInMap = 0;
4220 * struct bcm_dsd_header dsdHeader = {0};
4223 /* sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader; */
4225 if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) {
4226 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for DSDs");
4227 return STATUS_FAILURE;
4229 BcmFlash2xBulkRead(Adapter,
4230 &uiDSDsig,
4231 dsd,
4232 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber),
4233 SIGNATURE_SIZE);
4235 uiDSDsig = ntohl(uiDSDsig);
4236 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig);
4238 return uiDSDsig;
4241 int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd)
4243 /* unsigned int priOffsetInMap = 0 ; */
4244 unsigned int uiDSDPri = STATUS_FAILURE;
4245 /* struct bcm_dsd_header dsdHeader = {0};
4246 * priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
4248 if (IsSectionWritable(Adapter, dsd)) {
4249 if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) {
4250 BcmFlash2xBulkRead(Adapter,
4251 &uiDSDPri,
4252 dsd,
4253 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority),
4256 uiDSDPri = ntohl(uiDSDPri);
4257 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri);
4261 return uiDSDPri;
4264 enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter)
4266 int DSDHighestPri = STATUS_FAILURE;
4267 int DsdPri = 0;
4268 enum bcm_flash2x_section_val HighestPriDSD = 0;
4270 if (IsSectionWritable(Adapter, DSD2)) {
4271 DSDHighestPri = ReadDSDPriority(Adapter, DSD2);
4272 HighestPriDSD = DSD2;
4275 if (IsSectionWritable(Adapter, DSD1)) {
4276 DsdPri = ReadDSDPriority(Adapter, DSD1);
4277 if (DSDHighestPri < DsdPri) {
4278 DSDHighestPri = DsdPri;
4279 HighestPriDSD = DSD1;
4283 if (IsSectionWritable(Adapter, DSD0)) {
4284 DsdPri = ReadDSDPriority(Adapter, DSD0);
4285 if (DSDHighestPri < DsdPri) {
4286 DSDHighestPri = DsdPri;
4287 HighestPriDSD = DSD0;
4290 if (HighestPriDSD)
4291 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri);
4293 return HighestPriDSD;
4296 int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
4298 unsigned int uiISOsig = 0;
4299 /* unsigned int sigoffsetInMap = 0;
4300 * struct bcm_iso_header ISOHeader = {0};
4301 * sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
4303 if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) {
4304 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs");
4305 return STATUS_FAILURE;
4307 BcmFlash2xBulkRead(Adapter,
4308 &uiISOsig,
4309 iso,
4310 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber),
4311 SIGNATURE_SIZE);
4313 uiISOsig = ntohl(uiISOsig);
4314 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig);
4316 return uiISOsig;
4319 int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso)
4321 unsigned int ISOPri = STATUS_FAILURE;
4322 if (IsSectionWritable(Adapter, iso)) {
4323 if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) {
4324 BcmFlash2xBulkRead(Adapter,
4325 &ISOPri,
4326 iso,
4327 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority),
4330 ISOPri = ntohl(ISOPri);
4331 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri);
4335 return ISOPri;
4338 enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter)
4340 int ISOHighestPri = STATUS_FAILURE;
4341 int ISOPri = 0;
4342 enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL;
4344 if (IsSectionWritable(Adapter, ISO_IMAGE2)) {
4345 ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2);
4346 HighestPriISO = ISO_IMAGE2;
4349 if (IsSectionWritable(Adapter, ISO_IMAGE1)) {
4350 ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1);
4351 if (ISOHighestPri < ISOPri) {
4352 ISOHighestPri = ISOPri;
4353 HighestPriISO = ISO_IMAGE1;
4356 if (HighestPriISO)
4357 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest ISO :%x and its Pri :%x", HighestPriISO, ISOHighestPri);
4359 return HighestPriISO;
4362 int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
4363 PUINT pBuff,
4364 enum bcm_flash2x_section_val eFlash2xSectionVal,
4365 unsigned int uiOffset,
4366 unsigned int uiNumBytes)
4368 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
4369 unsigned int uiTemp = 0, value = 0;
4370 unsigned int i = 0;
4371 unsigned int uiPartOffset = 0;
4372 #endif
4373 unsigned int uiStartOffset = 0;
4374 /* Adding section start address */
4375 int Status = STATUS_SUCCESS;
4376 PUCHAR pcBuff = (PUCHAR)pBuff;
4378 if (uiNumBytes % Adapter->ulFlashWriteSize) {
4379 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
4380 return STATUS_FAILURE;
4383 uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
4385 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
4386 return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
4388 uiOffset = uiOffset + uiStartOffset;
4390 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS)
4391 Status = bcmflash_raw_writenoerase((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), pcBuff, uiNumBytes);
4392 #else
4393 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4394 value = 0;
4395 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
4397 Adapter->SelectedChip = RESET_CHIP_SELECT;
4398 BcmDoChipSelect(Adapter, uiOffset);
4399 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
4401 for (i = 0; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
4402 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
4403 Status = flashByteWrite(Adapter, uiPartOffset, pcBuff);
4404 else
4405 Status = flashWrite(Adapter, uiPartOffset, pcBuff);
4407 if (Status != STATUS_SUCCESS)
4408 break;
4410 pcBuff = pcBuff + Adapter->ulFlashWriteSize;
4411 uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize;
4413 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
4414 Adapter->SelectedChip = RESET_CHIP_SELECT;
4415 #endif
4417 return Status;
4420 bool IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section)
4422 bool SectionPresent = false;
4424 switch (section) {
4425 case ISO_IMAGE1:
4426 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) &&
4427 (IsNonCDLessDevice(Adapter) == false))
4428 SectionPresent = TRUE;
4429 break;
4430 case ISO_IMAGE2:
4431 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) &&
4432 (IsNonCDLessDevice(Adapter) == false))
4433 SectionPresent = TRUE;
4434 break;
4435 case DSD0:
4436 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS)
4437 SectionPresent = TRUE;
4438 break;
4439 case DSD1:
4440 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS)
4441 SectionPresent = TRUE;
4442 break;
4443 case DSD2:
4444 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS)
4445 SectionPresent = TRUE;
4446 break;
4447 case VSA0:
4448 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS)
4449 SectionPresent = TRUE;
4450 break;
4451 case VSA1:
4452 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS)
4453 SectionPresent = TRUE;
4454 break;
4455 case VSA2:
4456 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS)
4457 SectionPresent = TRUE;
4458 break;
4459 case SCSI:
4460 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS)
4461 SectionPresent = TRUE;
4462 break;
4463 case CONTROL_SECTION:
4464 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS)
4465 SectionPresent = TRUE;
4466 break;
4467 default:
4468 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x");
4469 SectionPresent = false;
4472 return SectionPresent;
4475 int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section)
4477 int offset = STATUS_FAILURE;
4478 int Status = false;
4480 if (IsSectionExistInFlash(Adapter, Section) == false) {
4481 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exist", Section);
4482 return false;
4485 offset = BcmGetSectionValStartOffset(Adapter, Section);
4486 if (offset == INVALID_OFFSET) {
4487 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exist", Section);
4488 return false;
4491 if (IsSectionExistInVendorInfo(Adapter, Section))
4492 return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
4494 Status = IsOffsetWritable(Adapter, offset);
4495 return Status;
4498 static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
4500 PUCHAR pBuff = NULL;
4501 unsigned int sig = 0;
4502 unsigned int uiOffset = 0;
4503 unsigned int BlockStatus = 0;
4504 unsigned int uiSectAlignAddr = 0;
4506 Adapter->bSigCorrupted = false;
4507 if (Adapter->bAllDSDWriteAllow == false) {
4508 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
4509 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
4510 return SECTOR_IS_NOT_WRITABLE;
4514 pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL);
4515 if (!pBuff) {
4516 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4517 return -ENOMEM;
4520 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header);
4521 uiOffset -= MAX_RW_SIZE;
4523 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
4525 sig = *((PUINT)(pBuff + 12));
4526 sig = ntohl(sig);
4527 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
4528 /* Now corrupting the sig by corrupting 4th last Byte. */
4529 *(pBuff + 12) = 0;
4531 if (sig == DSD_IMAGE_MAGIC_NUMBER) {
4532 Adapter->bSigCorrupted = TRUE;
4533 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) {
4534 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4535 BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
4537 WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal,
4538 (uiOffset + 12), BYTE_WRITE_SUPPORT);
4539 if (BlockStatus) {
4540 BcmRestoreBlockProtectStatus(Adapter, BlockStatus);
4541 BlockStatus = 0;
4543 } else {
4544 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4545 uiOffset, MAX_RW_SIZE);
4547 } else {
4548 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
4549 kfree(pBuff);
4551 return STATUS_FAILURE;
4554 kfree(pBuff);
4555 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
4557 return STATUS_SUCCESS;
4560 static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal)
4562 PUCHAR pBuff = NULL;
4563 unsigned int sig = 0;
4564 unsigned int uiOffset = 0;
4566 Adapter->bSigCorrupted = false;
4568 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
4569 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
4570 return SECTOR_IS_NOT_WRITABLE;
4573 pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL);
4574 if (!pBuff) {
4575 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4576 return -ENOMEM;
4579 uiOffset = 0;
4581 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
4583 sig = *((PUINT)pBuff);
4584 sig = ntohl(sig);
4586 /* corrupt signature */
4587 *pBuff = 0;
4589 if (sig == ISO_IMAGE_MAGIC_NUMBER) {
4590 Adapter->bSigCorrupted = TRUE;
4591 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4592 uiOffset, Adapter->ulFlashWriteSize);
4593 } else {
4594 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
4595 kfree(pBuff);
4597 return STATUS_FAILURE;
4600 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
4601 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE);
4603 kfree(pBuff);
4604 return STATUS_SUCCESS;
4607 bool IsNonCDLessDevice(struct bcm_mini_adapter *Adapter)
4609 if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
4610 return TRUE;
4611 else
4612 return false;