Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.10-rc5 4665 lines 165 kB view raw
1#include "headers.h" 2 3#define DWORD unsigned int 4 5static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset); 6static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter); 7static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter); 8static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter); 9static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter); 10static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize); 11 12static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter); 13static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter); 14static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter); 15static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter); 16 17static int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal); 18 19static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset); 20static int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section); 21static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section); 22 23static int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd); 24static int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd); 25static int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso); 26static int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso); 27 28static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal); 29static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal); 30static int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiSectAlignAddr); 31static int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff, 32 enum bcm_flash2x_section_val eFlash2xSectionVal, 33 unsigned int uiOffset, unsigned int uiNumBytes); 34static enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter); 35static enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter); 36 37static int BeceemFlashBulkRead( 38 struct bcm_mini_adapter *Adapter, 39 PUINT pBuffer, 40 unsigned int uiOffset, 41 unsigned int uiNumBytes); 42 43static int BeceemFlashBulkWrite( 44 struct bcm_mini_adapter *Adapter, 45 PUINT pBuffer, 46 unsigned int uiOffset, 47 unsigned int uiNumBytes, 48 BOOLEAN bVerify); 49 50static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter); 51 52static int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, unsigned int dwAddress, unsigned int *pdwData, unsigned int dwNumData); 53 54/* Procedure: ReadEEPROMStatusRegister 55 * 56 * Description: Reads the standard EEPROM Status Register. 57 * 58 * Arguments: 59 * Adapter - ptr to Adapter object instance 60 * Returns: 61 * OSAL_STATUS_CODE 62 */ 63static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter) 64{ 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; 70 71 /* Read the EEPROM status register */ 72 value = EEPROM_READ_STATUS_REGISTER; 73 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); 74 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; 82 } 83 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)); 89 90 value = 0; 91 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); 92 uiData = (UCHAR)value; 93 94 break; 95 } 96 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; 103 } 104 if (!(dwRetries%RETRIES_PER_DELAY)) 105 udelay(1000); 106 uiStatus = 0 ; 107 } 108 return uiData; 109} /* ReadEEPROMStatusRegister */ 110 111/* 112 * Procedure: ReadBeceemEEPROMBulk 113 * 114 * Description: This routine reads 16Byte data from EEPROM 115 * 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. 120 * 121 * Returns: 122 * OSAL_STATUS_CODE: 123 */ 124 125int ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, 126 DWORD dwAddress, 127 DWORD *pdwData, 128 DWORD dwNumWords) 129{ 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; 136 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)); 142 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)); 146 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)); 149 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; 156 } 157 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 161 */ 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; 168 } 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. 173 */ 174 if (Adapter->chip_id == 0xBECE0210) 175 udelay(800); 176 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; 181 } 182 } 183 184 uiStatus = 0; 185 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; 195 } 196 197 if (!(dwRetries%RETRIES_PER_DELAY)) 198 udelay(1000); 199 } 200 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); 204 205 value = 0; 206 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); 207 208 pvalue[0] = value; 209 210 value = 0; 211 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); 212 213 pvalue[1] = value; 214 215 value = 0; 216 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); 217 218 pvalue[2] = value; 219 220 value = 0; 221 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value)); 222 223 pvalue[3] = value; 224 } 225 226 return STATUS_SUCCESS; 227} /* ReadBeceemEEPROMBulk() */ 228 229/* 230 * Procedure: ReadBeceemEEPROM 231 * 232 * Description: This routine reads 4 data from EEPROM. It uses 1 or 2 page 233 * reads to do this operation. 234 * 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. 239 * 240 * Returns: 241 * OSAL_STATUS_CODE: 242 */ 243 244int ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter, 245 DWORD uiOffset, 246 DWORD *pBuffer) 247{ 248 unsigned int uiData[8] = {0}; 249 unsigned int uiByteOffset = 0; 250 unsigned int uiTempOffset = 0; 251 252 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ====> "); 253 254 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); 255 uiByteOffset = uiOffset - uiTempOffset; 256 257 ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4); 258 259 /* A word can overlap at most over 2 pages. In that case we read the 260 * next page too. 261 */ 262 if (uiByteOffset > 12) 263 ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4); 264 265 memcpy((PUCHAR)pBuffer, (((PUCHAR)&uiData[0]) + uiByteOffset), 4); 266 267 return STATUS_SUCCESS; 268} /* ReadBeceemEEPROM() */ 269 270int ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter) 271{ 272 int Status; 273 unsigned char puMacAddr[6]; 274 275 Status = BeceemNVMRead(Adapter, 276 (PUINT)&puMacAddr[0], 277 INIT_PARAMS_1_MACADDRESS_ADDRESS, 278 MAC_ADDRESS_SIZE); 279 280 if (Status == STATUS_SUCCESS) 281 memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); 282 283 return Status; 284} 285 286/* 287 * Procedure: BeceemEEPROMBulkRead 288 * 289 * Description: Reads the EEPROM and returns the Data. 290 * 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. 296 * 297 * Returns: 298 * OSAL_STATUS_SUCCESS - if EEPROM read is successful. 299 * <FAILURE> - if failed. 300 */ 301 302int BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter, 303 PUINT pBuffer, 304 unsigned int uiOffset, 305 unsigned int uiNumBytes) 306{ 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; 315 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; 330 } 331 } 332 333 while (uiBytesRemaining && uiFailureRetries != 128) { 334 if (Adapter->device_removed) 335 return -1; 336 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 341 */ 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... */ 350 } 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... */ 360 } 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... */ 371 } 372 } 373 } 374 375 return 0; 376} 377 378/* 379 * Procedure: BeceemFlashBulkRead 380 * 381 * Description: Reads the FLASH and returns the Data. 382 * 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. 388 * 389 * Returns: 390 * OSAL_STATUS_SUCCESS - if FLASH read is successful. 391 * <FAILURE> - if failed. 392 */ 393 394static int BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter, 395 PUINT pBuffer, 396 unsigned int uiOffset, 397 unsigned int uiNumBytes) 398{ 399 unsigned int uiIndex = 0; 400 unsigned int uiBytesToRead = uiNumBytes; 401 int Status = 0; 402 unsigned int uiPartOffset = 0; 403 int bytes; 404 405 if (Adapter->device_removed) { 406 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed"); 407 return -ENODEV; 408 } 409 410 /* Adding flash Base address 411 * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); 412 */ 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 417 418 Adapter->SelectedChip = RESET_CHIP_SELECT; 419 420 if (uiOffset % MAX_RW_SIZE) { 421 BcmDoChipSelect(Adapter, uiOffset); 422 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); 423 424 uiBytesToRead = MAX_RW_SIZE - (uiOffset % MAX_RW_SIZE); 425 uiBytesToRead = MIN(uiNumBytes, uiBytesToRead); 426 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; 432 } 433 434 uiIndex += uiBytesToRead; 435 uiOffset += uiBytesToRead; 436 uiNumBytes -= uiBytesToRead; 437 } 438 439 while (uiNumBytes) { 440 BcmDoChipSelect(Adapter, uiOffset); 441 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); 442 443 uiBytesToRead = MIN(uiNumBytes, MAX_RW_SIZE); 444 445 bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead); 446 if (bytes < 0) { 447 Status = bytes; 448 break; 449 } 450 451 uiIndex += uiBytesToRead; 452 uiOffset += uiBytesToRead; 453 uiNumBytes -= uiBytesToRead; 454 } 455 Adapter->SelectedChip = RESET_CHIP_SELECT; 456 return Status; 457} 458 459/* 460 * Procedure: BcmGetFlashSize 461 * 462 * Description: Finds the size of FLASH. 463 * 464 * Arguments: 465 * Adapter - ptr to Adapter object instance 466 * 467 * Returns: 468 * unsigned int - size of the FLASH Storage. 469 * 470 */ 471 472static unsigned int BcmGetFlashSize(struct bcm_mini_adapter *Adapter) 473{ 474 if (IsFlash2x(Adapter)) 475 return Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header); 476 else 477 return 32 * 1024; 478} 479 480/* 481 * Procedure: BcmGetEEPROMSize 482 * 483 * Description: Finds the size of EEPROM. 484 * 485 * Arguments: 486 * Adapter - ptr to Adapter object instance 487 * 488 * Returns: 489 * unsigned int - size of the EEPROM Storage. 490 * 491 */ 492 493static unsigned int BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter) 494{ 495 unsigned int uiData = 0; 496 unsigned int uiIndex = 0; 497 498 /* 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. 505 */ 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; 512 } 513 } else { 514 /* 515 * EEPROM may not be present or not programmed 516 */ 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; 524 } 525 } 526 } 527 return 0; 528} 529 530/* 531 * Procedure: FlashSectorErase 532 * 533 * Description: Finds the sector size of the FLASH. 534 * 535 * Arguments: 536 * Adapter - ptr to Adapter object instance 537 * addr - sector start address 538 * numOfSectors - number of sectors to be erased. 539 * 540 * Returns: 541 * OSAL_STATUS_CODE 542 * 543 */ 544 545static int FlashSectorErase(struct bcm_mini_adapter *Adapter, 546 unsigned int addr, 547 unsigned int numOfSectors) 548{ 549 unsigned int iIndex = 0, iRetries = 0; 550 unsigned int uiStatus = 0; 551 unsigned int value; 552 int bytes; 553 554 for (iIndex = 0; iIndex < numOfSectors; iIndex++) { 555 value = 0x06000000; 556 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); 557 558 value = (0xd8000000 | (addr & 0xFFFFFF)); 559 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); 560 iRetries = 0; 561 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; 567 } 568 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; 574 } 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. 579 */ 580 mdelay(10); 581 } while ((uiStatus & 0x1) && (iRetries < 400)); 582 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; 586 } 587 588 addr += Adapter->uiSectorSize; 589 } 590 return 0; 591} 592/* 593 * Procedure: flashByteWrite 594 * 595 * Description: Performs Byte by Byte write to flash 596 * 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 603 * 604 */ 605 606static int flashByteWrite(struct bcm_mini_adapter *Adapter, 607 unsigned int uiOffset, 608 PVOID pData) 609{ 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; 615 /* 616 * need not write 0xFF because write requires an erase and erase will 617 * make whole sector 0xFF. 618 */ 619 620 if (0xFF == ulData) 621 return STATUS_SUCCESS; 622 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; 628 } 629 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; 633 } 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; 638 } 639 640 /* __udelay(950); */ 641 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; 647 } 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; 654 } 655 iRetries--; 656 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) 657 udelay(1000); 658 659 } while ((uiStatus & 0x1) && (iRetries > 0)); 660 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; 664 } 665 666 return STATUS_SUCCESS; 667} 668 669/* 670 * Procedure: flashWrite 671 * 672 * Description: Performs write to flash 673 * 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 680 * 681 */ 682 683static int flashWrite(struct bcm_mini_adapter *Adapter, 684 unsigned int uiOffset, 685 PVOID pData) 686{ 687 /* unsigned int uiStatus = 0; 688 * int iRetries = 0; 689 * unsigned int uiReadBack = 0; 690 */ 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; 696 /* 697 * need not write 0xFFFFFFFF because write requires an erase and erase will 698 * make whole sector 0xFFFFFFFF. 699 */ 700 if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) 701 return 0; 702 703 value = (FLASH_CMD_WRITE_ENABLE << 24); 704 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; 708 } 709 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; 713 } 714 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; 721 } 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; 728 } 729 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 735 */ 736 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) 737 udelay(1000); 738 } while ((uiStatus & 0x1) && (iRetries > 0)); 739 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; 743 } 744 745 return STATUS_SUCCESS; 746} 747 748/*----------------------------------------------------------------------------- 749 * Procedure: flashByteWriteStatus 750 * 751 * Description: Performs byte by byte write to flash with write done status check 752 * 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 759 * 760 */ 761static int flashByteWriteStatus(struct bcm_mini_adapter *Adapter, 762 unsigned int uiOffset, 763 PVOID pData) 764{ 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; 770 771 /* 772 * need not write 0xFFFFFFFF because write requires an erase and erase will 773 * make whole sector 0xFFFFFFFF. 774 */ 775 776 if (0xFF == ulData) 777 return STATUS_SUCCESS; 778 779 /* DumpDebug(NVM_RW,("flashWrite ====>\n")); */ 780 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; 785 } 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; 789 } 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; 794 } 795 796 /* msleep(1); */ 797 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; 803 } 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; 810 } 811 812 iRetries--; 813 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) 814 udelay(1000); 815 816 } while ((uiStatus & 0x1) && (iRetries > 0)); 817 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; 821 } 822 823 return STATUS_SUCCESS; 824} 825/* 826 * Procedure: flashWriteStatus 827 * 828 * Description: Performs write to flash with write done status check 829 * 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 836 * 837 */ 838 839static int flashWriteStatus(struct bcm_mini_adapter *Adapter, 840 unsigned int uiOffset, 841 PVOID pData) 842{ 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; 849 850 /* 851 * need not write 0xFFFFFFFF because write requires an erase and erase will 852 * make whole sector 0xFFFFFFFF. 853 */ 854 if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) 855 return 0; 856 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; 861 } 862 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; 866 } 867 /* __udelay(1); */ 868 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; 874 } 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; 881 } 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 887 */ 888 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0)) 889 udelay(1000); 890 891 } while ((uiStatus & 0x1) && (iRetries > 0)); 892 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; 896 } 897 898 return STATUS_SUCCESS; 899} 900 901/* 902 * Procedure: BcmRestoreBlockProtectStatus 903 * 904 * Description: Restores the original block protection status. 905 * 906 * Arguments: 907 * Adapter - ptr to Adapter object instance 908 * ulWriteStatus -Original status 909 * Returns: 910 * <VOID> 911 * 912 */ 913 914static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus) 915{ 916 unsigned int value; 917 value = (FLASH_CMD_WRITE_ENABLE << 24); 918 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); 919 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); 924} 925 926/* 927 * Procedure: BcmFlashUnProtectBlock 928 * 929 * Description: UnProtects appropriate blocks for writing. 930 * 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. 936 * 937 */ 938 939static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, unsigned int uiOffset, unsigned int uiLength) 940{ 941 ULONG ulStatus = 0; 942 ULONG ulWriteStatus = 0; 943 unsigned int value; 944 945 uiOffset = uiOffset&0x000FFFFF; 946 /* 947 * Implemented only for 1MB Flash parts. 948 */ 949 if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) { 950 /* 951 * Get Current BP status. 952 */ 953 value = (FLASH_CMD_STATUS_REG_READ << 24); 954 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); 955 udelay(10); 956 /* 957 * Read status will be WWXXYYZZ. We have to take only WW. 958 */ 959 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus)); 960 ulStatus >>= 24; 961 ulWriteStatus = ulStatus; 962 /* 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 967 */ 968 969 if (ulStatus) { 970 if ((uiOffset+uiLength) <= 0x80000) { 971 /* 972 * Offset comes in lower half of 1MB. Protect the upper half. 973 * Clear BP1 and BP0 and set BP2. 974 */ 975 ulWriteStatus |= (0x4<<2); 976 ulWriteStatus &= ~(0x3<<2); 977 } else if ((uiOffset + uiLength) <= 0xC0000) { 978 /* 979 * Offset comes below Upper 1/4. Upper 1/4 can be protected. 980 * Clear BP2 and set BP1 and BP0. 981 */ 982 ulWriteStatus |= (0x3<<2); 983 ulWriteStatus &= ~(0x1<<4); 984 } else if ((uiOffset + uiLength) <= 0xE0000) { 985 /* 986 * Offset comes below Upper 1/8. Upper 1/8 can be protected. 987 * Clear BP2 and BP0 and set BP1 988 */ 989 ulWriteStatus |= (0x1<<3); 990 ulWriteStatus &= ~(0x5<<2); 991 } else if ((uiOffset + uiLength) <= 0xF0000) { 992 /* 993 * Offset comes below Upper 1/16. Only upper 1/16 can be protected. 994 * Set BP0 and Clear BP2,BP1. 995 */ 996 ulWriteStatus |= (0x1<<2); 997 ulWriteStatus &= ~(0x3<<3); 998 } else { 999 /* 1000 * Unblock all. 1001 * Clear BP2,BP1 and BP0. 1002 */ 1003 ulWriteStatus &= ~(0x7<<2); 1004 } 1005 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); 1012 } 1013 } 1014 return ulStatus; 1015} 1016 1017/* 1018 * Procedure: BeceemFlashBulkWrite 1019 * 1020 * Description: Performs write to the flash 1021 * 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 1030 * 1031 */ 1032 1033static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter, 1034 PUINT pBuffer, 1035 unsigned int uiOffset, 1036 unsigned int uiNumBytes, 1037 BOOLEAN bVerify) 1038{ 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; 1053 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 1058 1059 uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); 1060 1061 /* Adding flash Base address 1062 * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); 1063 */ 1064 1065 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); 1066 uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); 1067 uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; 1068 1069 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); 1070 if (!pTempBuff) 1071 goto BeceemFlashBulkWrite_EXIT; 1072 /* 1073 * check if the data to be written is overlapped across sectors 1074 */ 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++; 1082 } 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 1085 */ 1086 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; 1096 } 1097 uiTemp = uiTemp - 1; 1098 index = index + 1 ; 1099 } 1100 } 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)); 1105 */ 1106 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); 1107 1108 BcmDoChipSelect(Adapter, uiSectAlignAddr); 1109 1110 if (0 != BeceemFlashBulkRead(Adapter, 1111 (PUINT)pTempBuff, 1112 uiOffsetFromSectStart, 1113 Adapter->uiSectorSize)) { 1114 Status = -1; 1115 goto BeceemFlashBulkWrite_EXIT; 1116 } 1117 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)); 1120 */ 1121 ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); 1122 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); 1129 } 1130 1131 if (IsFlash2x(Adapter)) 1132 SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); 1133 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)); 1137 */ 1138 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { 1139 if (Adapter->device_removed) { 1140 Status = -1; 1141 goto BeceemFlashBulkWrite_EXIT; 1142 } 1143 1144 if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) { 1145 Status = -1; 1146 goto BeceemFlashBulkWrite_EXIT; 1147 } 1148 } 1149 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)); 1152 */ 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; 1162 } 1163 } 1164 } 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; 1170 } 1171 } 1172 } 1173 } 1174 } 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)); 1177 */ 1178 if (ulStatus) { 1179 BcmRestoreBlockProtectStatus(Adapter, ulStatus); 1180 ulStatus = 0; 1181 } 1182 1183 uiCurrSectOffsetAddr = 0; 1184 uiSectAlignAddr = uiSectBoundary; 1185 uiSectBoundary += Adapter->uiSectorSize; 1186 uiOffsetFromSectStart += Adapter->uiSectorSize; 1187 uiNumSectTobeRead--; 1188 } 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)); 1192 * 1193 * Cleanup. 1194 */ 1195BeceemFlashBulkWrite_EXIT: 1196 if (ulStatus) 1197 BcmRestoreBlockProtectStatus(Adapter, ulStatus); 1198 1199 kfree(pTempBuff); 1200 1201 Adapter->SelectedChip = RESET_CHIP_SELECT; 1202 return Status; 1203} 1204 1205/* 1206 * Procedure: BeceemFlashBulkWriteStatus 1207 * 1208 * Description: Writes to Flash. Checks the SPI status after each write. 1209 * 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 1218 * 1219 */ 1220 1221static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter, 1222 PUINT pBuffer, 1223 unsigned int uiOffset, 1224 unsigned int uiNumBytes, 1225 BOOLEAN bVerify) 1226{ 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; 1241 1242 uiOffsetFromSectStart = uiOffset & ~(Adapter->uiSectorSize - 1); 1243 1244 /* uiOffset += Adapter->ulFlashCalStart; 1245 * Adding flash Base address 1246 * uiOffset = uiOffset + GetFlashBaseAddr(Adapter); 1247 */ 1248 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); 1249 uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); 1250 uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; 1251 1252 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); 1253 if (!pTempBuff) 1254 goto BeceemFlashBulkWriteStatus_EXIT; 1255 1256 /* 1257 * check if the data to be written is overlapped across sectors 1258 */ 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++; 1266 } 1267 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; 1277 } 1278 uiTemp = uiTemp - 1; 1279 index = index + 1 ; 1280 } 1281 } 1282 1283 Adapter->SelectedChip = RESET_CHIP_SELECT; 1284 while (uiNumSectTobeRead) { 1285 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); 1286 1287 BcmDoChipSelect(Adapter, uiSectAlignAddr); 1288 if (0 != BeceemFlashBulkRead(Adapter, 1289 (PUINT)pTempBuff, 1290 uiOffsetFromSectStart, 1291 Adapter->uiSectorSize)) { 1292 Status = -1; 1293 goto BeceemFlashBulkWriteStatus_EXIT; 1294 } 1295 1296 ulStatus = BcmFlashUnProtectBlock(Adapter, uiOffsetFromSectStart, Adapter->uiSectorSize); 1297 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); 1304 } 1305 1306 if (IsFlash2x(Adapter)) 1307 SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart); 1308 1309 FlashSectorErase(Adapter, uiPartOffset, 1); 1310 1311 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) { 1312 if (Adapter->device_removed) { 1313 Status = -1; 1314 goto BeceemFlashBulkWriteStatus_EXIT; 1315 } 1316 1317 if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) { 1318 Status = -1; 1319 goto BeceemFlashBulkWriteStatus_EXIT; 1320 } 1321 } 1322 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; 1329 } 1330 } 1331 } 1332 } 1333 1334 if (ulStatus) { 1335 BcmRestoreBlockProtectStatus(Adapter, ulStatus); 1336 ulStatus = 0; 1337 } 1338 1339 uiCurrSectOffsetAddr = 0; 1340 uiSectAlignAddr = uiSectBoundary; 1341 uiSectBoundary += Adapter->uiSectorSize; 1342 uiOffsetFromSectStart += Adapter->uiSectorSize; 1343 uiNumSectTobeRead--; 1344 } 1345/* 1346 * Cleanup. 1347 */ 1348BeceemFlashBulkWriteStatus_EXIT: 1349 if (ulStatus) 1350 BcmRestoreBlockProtectStatus(Adapter, ulStatus); 1351 1352 kfree(pTempBuff); 1353 Adapter->SelectedChip = RESET_CHIP_SELECT; 1354 return Status; 1355} 1356 1357/* 1358 * Procedure: PropagateCalParamsFromEEPROMToMemory 1359 * 1360 * Description: Dumps the calibration section of EEPROM to DDR. 1361 * 1362 * Arguments: 1363 * Adapter - ptr to Adapter object instance 1364 * Returns: 1365 * OSAL_STATUS_CODE 1366 * 1367 */ 1368 1369int PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) 1370{ 1371 PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL); 1372 unsigned int uiEepromSize = 0; 1373 unsigned int uiIndex = 0; 1374 unsigned int uiBytesToCopy = 0; 1375 unsigned int uiCalStartAddr = EEPROM_CALPARAM_START; 1376 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; 1377 unsigned int value; 1378 int Status = 0; 1379 1380 if (!pBuff) 1381 return -ENOMEM; 1382 1383 if (0 != BeceemEEPROMBulkRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) { 1384 kfree(pBuff); 1385 return -1; 1386 } 1387 1388 uiEepromSize >>= 16; 1389 if (uiEepromSize > 1024 * 1024) { 1390 kfree(pBuff); 1391 return -1; 1392 } 1393 1394 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); 1395 1396 while (uiBytesToCopy) { 1397 if (0 != BeceemEEPROMBulkRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiBytesToCopy)) { 1398 Status = -1; 1399 break; 1400 } 1401 wrm(Adapter, uiMemoryLoc, (PCHAR)(((PULONG)pBuff) + uiIndex), uiBytesToCopy); 1402 uiMemoryLoc += uiBytesToCopy; 1403 uiEepromSize -= uiBytesToCopy; 1404 uiCalStartAddr += uiBytesToCopy; 1405 uiIndex += uiBytesToCopy / 4; 1406 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); 1407 1408 } 1409 value = 0xbeadbead; 1410 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); 1411 value = 0xbeadbead; 1412 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); 1413 kfree(pBuff); 1414 1415 return Status; 1416} 1417 1418/* 1419 * Procedure: PropagateCalParamsFromFlashToMemory 1420 * 1421 * Description: Dumps the calibration section of EEPROM to DDR. 1422 * 1423 * Arguments: 1424 * Adapter - ptr to Adapter object instance 1425 * Returns: 1426 * OSAL_STATUS_CODE 1427 * 1428 */ 1429 1430int PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter) 1431{ 1432 PCHAR pBuff, pPtr; 1433 unsigned int uiEepromSize = 0; 1434 unsigned int uiBytesToCopy = 0; 1435 /* unsigned int uiIndex = 0; */ 1436 unsigned int uiCalStartAddr = EEPROM_CALPARAM_START; 1437 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; 1438 unsigned int value; 1439 int Status = 0; 1440 1441 /* 1442 * Write the signature first. This will ensure firmware does not access EEPROM. 1443 */ 1444 value = 0xbeadbead; 1445 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); 1446 value = 0xbeadbead; 1447 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); 1448 1449 if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) 1450 return -1; 1451 1452 uiEepromSize = ntohl(uiEepromSize); 1453 uiEepromSize >>= 16; 1454 1455 /* 1456 * subtract the auto init section size 1457 */ 1458 uiEepromSize -= EEPROM_CALPARAM_START; 1459 1460 if (uiEepromSize > 1024 * 1024) 1461 return -1; 1462 1463 pBuff = kmalloc(uiEepromSize, GFP_KERNEL); 1464 if (pBuff == NULL) 1465 return -ENOMEM; 1466 1467 if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) { 1468 kfree(pBuff); 1469 return -1; 1470 } 1471 1472 pPtr = pBuff; 1473 1474 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); 1475 1476 while (uiBytesToCopy) { 1477 Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy); 1478 if (Status) { 1479 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status); 1480 break; 1481 } 1482 1483 pPtr += uiBytesToCopy; 1484 uiEepromSize -= uiBytesToCopy; 1485 uiMemoryLoc += uiBytesToCopy; 1486 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); 1487 } 1488 1489 kfree(pBuff); 1490 return Status; 1491} 1492 1493/* 1494 * Procedure: BeceemEEPROMReadBackandVerify 1495 * 1496 * Description: Read back the data written and verifies. 1497 * 1498 * Arguments: 1499 * Adapter - ptr to Adapter object instance 1500 * pBuffer - Data to be written. 1501 * uiOffset - Offset of the flash where data needs to be written to. 1502 * uiNumBytes - Number of bytes to be written. 1503 * Returns: 1504 * OSAL_STATUS_CODE 1505 * 1506 */ 1507 1508static int BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter, 1509 PUINT pBuffer, 1510 unsigned int uiOffset, 1511 unsigned int uiNumBytes) 1512{ 1513 unsigned int uiRdbk = 0; 1514 unsigned int uiIndex = 0; 1515 unsigned int uiData = 0; 1516 unsigned int auiData[4] = {0}; 1517 1518 while (uiNumBytes) { 1519 if (Adapter->device_removed) 1520 return -1; 1521 1522 if (uiNumBytes >= MAX_RW_SIZE) { 1523 /* for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. */ 1524 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); 1525 1526 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) { 1527 /* re-write */ 1528 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, FALSE); 1529 mdelay(3); 1530 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE); 1531 1532 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) 1533 return -1; 1534 } 1535 uiOffset += MAX_RW_SIZE; 1536 uiNumBytes -= MAX_RW_SIZE; 1537 uiIndex += 4; 1538 } else if (uiNumBytes >= 4) { 1539 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); 1540 if (uiData != pBuffer[uiIndex]) { 1541 /* re-write */ 1542 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, FALSE); 1543 mdelay(3); 1544 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4); 1545 if (uiData != pBuffer[uiIndex]) 1546 return -1; 1547 } 1548 uiOffset += 4; 1549 uiNumBytes -= 4; 1550 uiIndex++; 1551 } else { 1552 /* Handle the reads less than 4 bytes... */ 1553 uiData = 0; 1554 memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(unsigned int)), uiNumBytes); 1555 BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4); 1556 1557 if (memcmp(&uiData, &uiRdbk, uiNumBytes)) 1558 return -1; 1559 1560 uiNumBytes = 0; 1561 } 1562 } 1563 1564 return 0; 1565} 1566 1567static VOID BcmSwapWord(unsigned int *ptr1) 1568{ 1569 unsigned int tempval = (unsigned int)*ptr1; 1570 char *ptr2 = (char *)&tempval; 1571 char *ptr = (char *)ptr1; 1572 1573 ptr[0] = ptr2[3]; 1574 ptr[1] = ptr2[2]; 1575 ptr[2] = ptr2[1]; 1576 ptr[3] = ptr2[0]; 1577} 1578 1579/* 1580 * Procedure: BeceemEEPROMWritePage 1581 * 1582 * Description: Performs page write (16bytes) to the EEPROM 1583 * 1584 * Arguments: 1585 * Adapter - ptr to Adapter object instance 1586 * uiData - Data to be written. 1587 * uiOffset - Offset of the EEPROM where data needs to be written to. 1588 * Returns: 1589 * OSAL_STATUS_CODE 1590 * 1591 */ 1592 1593static int BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, unsigned int uiData[], unsigned int uiOffset) 1594{ 1595 unsigned int uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; 1596 unsigned int uiStatus = 0; 1597 UCHAR uiEpromStatus = 0; 1598 unsigned int value = 0; 1599 1600 /* Flush the Write/Read/Cmd queues. */ 1601 value = (EEPROM_WRITE_QUEUE_FLUSH | EEPROM_CMD_QUEUE_FLUSH | EEPROM_READ_QUEUE_FLUSH); 1602 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); 1603 value = 0; 1604 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); 1605 1606 /* Clear the Empty/Avail/Full bits. After this it has been confirmed 1607 * that the bit was cleared by reading back the register. See NOTE below. 1608 * We also clear the Read queues as we do a EEPROM status register read 1609 * later. 1610 */ 1611 value = (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL | EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL); 1612 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); 1613 1614 /* Enable write */ 1615 value = EEPROM_WRITE_ENABLE; 1616 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); 1617 1618 /* We can write back to back 8bits * 16 into the queue and as we have 1619 * checked for the queue to be empty we can write in a burst. 1620 */ 1621 1622 value = uiData[0]; 1623 BcmSwapWord(&value); 1624 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); 1625 1626 value = uiData[1]; 1627 BcmSwapWord(&value); 1628 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); 1629 1630 value = uiData[2]; 1631 BcmSwapWord(&value); 1632 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); 1633 1634 value = uiData[3]; 1635 BcmSwapWord(&value); 1636 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4); 1637 1638 /* NOTE : After this write, on readback of EEPROM_SPI_Q_STATUS1_REG 1639 * shows that we see 7 for the EEPROM data write. Which means that 1640 * queue got full, also space is available as well as the queue is empty. 1641 * This may happen in sequence. 1642 */ 1643 value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset; 1644 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value)); 1645 1646 /* Ideally we should loop here without tries and eventually succeed. 1647 * What we are checking if the previous write has completed, and this 1648 * may take time. We should wait till the Empty bit is set. 1649 */ 1650 uiStatus = 0; 1651 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); 1652 while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) { 1653 uiRetries--; 1654 if (uiRetries == 0) { 1655 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, %d retries failed.\n", uiStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); 1656 return STATUS_FAILURE; 1657 } 1658 1659 if (!(uiRetries%RETRIES_PER_DELAY)) 1660 udelay(1000); 1661 1662 uiStatus = 0; 1663 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus)); 1664 if (Adapter->device_removed == TRUE) { 1665 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop...."); 1666 return -ENODEV; 1667 } 1668 } 1669 1670 if (uiRetries != 0) { 1671 /* Clear the ones that are set - either, Empty/Full/Avail bits */ 1672 value = (uiStatus & (EEPROM_WRITE_QUEUE_EMPTY | EEPROM_WRITE_QUEUE_AVAIL | EEPROM_WRITE_QUEUE_FULL)); 1673 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); 1674 } 1675 1676 /* Here we should check if the EEPROM status register is correct before 1677 * proceeding. Bit 0 in the EEPROM Status register should be 0 before 1678 * we proceed further. A 1 at Bit 0 indicates that the EEPROM is busy 1679 * with the previous write. Note also that issuing this read finally 1680 * means the previous write to the EEPROM has completed. 1681 */ 1682 uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY; 1683 uiEpromStatus = 0; 1684 while (uiRetries != 0) { 1685 uiEpromStatus = ReadEEPROMStatusRegister(Adapter); 1686 if (Adapter->device_removed == TRUE) { 1687 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop..."); 1688 return -ENODEV; 1689 } 1690 if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) { 1691 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM status register = %x tries = %d\n", uiEpromStatus, (MAX_EEPROM_RETRIES * RETRIES_PER_DELAY - uiRetries)); 1692 return STATUS_SUCCESS; 1693 } 1694 uiRetries--; 1695 if (uiRetries == 0) { 1696 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "0x0f003004 = %x, for EEPROM status read %d retries failed.\n", uiEpromStatus, MAX_EEPROM_RETRIES * RETRIES_PER_DELAY); 1697 return STATUS_FAILURE; 1698 } 1699 uiEpromStatus = 0; 1700 if (!(uiRetries%RETRIES_PER_DELAY)) 1701 udelay(1000); 1702 } 1703 1704 return STATUS_SUCCESS; 1705} /* BeceemEEPROMWritePage */ 1706 1707/* 1708 * Procedure: BeceemEEPROMBulkWrite 1709 * 1710 * Description: Performs write to the EEPROM 1711 * 1712 * Arguments: 1713 * Adapter - ptr to Adapter object instance 1714 * pBuffer - Data to be written. 1715 * uiOffset - Offset of the EEPROM where data needs to be written to. 1716 * uiNumBytes - Number of bytes to be written. 1717 * bVerify - read verify flag. 1718 * Returns: 1719 * OSAL_STATUS_CODE 1720 * 1721 */ 1722 1723int BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter, 1724 PUCHAR pBuffer, 1725 unsigned int uiOffset, 1726 unsigned int uiNumBytes, 1727 BOOLEAN bVerify) 1728{ 1729 unsigned int uiBytesToCopy = uiNumBytes; 1730 /* unsigned int uiRdbk = 0; */ 1731 unsigned int uiData[4] = {0}; 1732 unsigned int uiIndex = 0; 1733 unsigned int uiTempOffset = 0; 1734 unsigned int uiExtraBytes = 0; 1735 /* PUINT puiBuffer = (PUINT)pBuffer; 1736 * int value; 1737 */ 1738 1739 if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) { 1740 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE); 1741 uiExtraBytes = uiOffset - uiTempOffset; 1742 1743 BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE); 1744 1745 if (uiBytesToCopy >= (16 - uiExtraBytes)) { 1746 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes); 1747 1748 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) 1749 return STATUS_FAILURE; 1750 1751 uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes); 1752 uiIndex += (MAX_RW_SIZE - uiExtraBytes); 1753 uiOffset += (MAX_RW_SIZE - uiExtraBytes); 1754 } else { 1755 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy); 1756 1757 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset)) 1758 return STATUS_FAILURE; 1759 1760 uiIndex += uiBytesToCopy; 1761 uiOffset += uiBytesToCopy; 1762 uiBytesToCopy = 0; 1763 } 1764 } 1765 1766 while (uiBytesToCopy) { 1767 if (Adapter->device_removed) 1768 return -1; 1769 1770 if (uiBytesToCopy >= MAX_RW_SIZE) { 1771 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset)) 1772 return STATUS_FAILURE; 1773 1774 uiIndex += MAX_RW_SIZE; 1775 uiOffset += MAX_RW_SIZE; 1776 uiBytesToCopy -= MAX_RW_SIZE; 1777 } else { 1778 /* 1779 * To program non 16byte aligned data, read 16byte and then update. 1780 */ 1781 BeceemEEPROMBulkRead(Adapter, &uiData[0], uiOffset, 16); 1782 memcpy(&uiData[0], pBuffer + uiIndex, uiBytesToCopy); 1783 1784 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiOffset)) 1785 return STATUS_FAILURE; 1786 1787 uiBytesToCopy = 0; 1788 } 1789 } 1790 1791 return 0; 1792} 1793 1794/* 1795 * Procedure: BeceemNVMRead 1796 * 1797 * Description: Reads n number of bytes from NVM. 1798 * 1799 * Arguments: 1800 * Adapter - ptr to Adapter object instance 1801 * pBuffer - Buffer to store the data read from NVM 1802 * uiOffset - Offset of NVM from where data should be read 1803 * uiNumBytes - Number of bytes to be read from the NVM. 1804 * 1805 * Returns: 1806 * OSAL_STATUS_SUCCESS - if NVM read is successful. 1807 * <FAILURE> - if failed. 1808 */ 1809 1810int BeceemNVMRead(struct bcm_mini_adapter *Adapter, 1811 PUINT pBuffer, 1812 unsigned int uiOffset, 1813 unsigned int uiNumBytes) 1814{ 1815 int Status = 0; 1816 1817 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) 1818 unsigned int uiTemp = 0, value; 1819 #endif 1820 1821 if (Adapter->eNVMType == NVM_FLASH) { 1822 if (Adapter->bFlashRawRead == FALSE) { 1823 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) 1824 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes); 1825 1826 uiOffset = uiOffset + Adapter->ulFlashCalStart; 1827 } 1828 1829 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) 1830 Status = bcmflash_raw_read((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); 1831 #else 1832 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 1833 value = 0; 1834 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); 1835 Status = BeceemFlashBulkRead(Adapter, 1836 pBuffer, 1837 uiOffset, 1838 uiNumBytes); 1839 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 1840 #endif 1841 } else if (Adapter->eNVMType == NVM_EEPROM) { 1842 Status = BeceemEEPROMBulkRead(Adapter, 1843 pBuffer, 1844 uiOffset, 1845 uiNumBytes); 1846 } else { 1847 Status = -1; 1848 } 1849 1850 return Status; 1851} 1852 1853/* 1854 * Procedure: BeceemNVMWrite 1855 * 1856 * Description: Writes n number of bytes to NVM. 1857 * 1858 * Arguments: 1859 * Adapter - ptr to Adapter object instance 1860 * pBuffer - Buffer contains the data to be written. 1861 * uiOffset - Offset of NVM where data to be written to. 1862 * uiNumBytes - Number of bytes to be written.. 1863 * 1864 * Returns: 1865 * OSAL_STATUS_SUCCESS - if NVM write is successful. 1866 * <FAILURE> - if failed. 1867 */ 1868 1869int BeceemNVMWrite(struct bcm_mini_adapter *Adapter, 1870 PUINT pBuffer, 1871 unsigned int uiOffset, 1872 unsigned int uiNumBytes, 1873 BOOLEAN bVerify) 1874{ 1875 int Status = 0; 1876 unsigned int uiTemp = 0; 1877 unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; 1878 unsigned int uiIndex = 0; 1879 1880 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) 1881 unsigned int value; 1882 #endif 1883 1884 unsigned int uiFlashOffset = 0; 1885 1886 if (Adapter->eNVMType == NVM_FLASH) { 1887 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD)) 1888 Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify); 1889 else { 1890 uiFlashOffset = uiOffset + Adapter->ulFlashCalStart; 1891 1892 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) 1893 Status = bcmflash_raw_write((uiFlashOffset / FLASH_PART_SIZE), (uiFlashOffset % FLASH_PART_SIZE), (unsigned char *)pBuffer, uiNumBytes); 1894 #else 1895 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 1896 value = 0; 1897 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); 1898 1899 if (Adapter->bStatusWrite == TRUE) 1900 Status = BeceemFlashBulkWriteStatus(Adapter, 1901 pBuffer, 1902 uiFlashOffset, 1903 uiNumBytes , 1904 bVerify); 1905 else 1906 1907 Status = BeceemFlashBulkWrite(Adapter, 1908 pBuffer, 1909 uiFlashOffset, 1910 uiNumBytes, 1911 bVerify); 1912 #endif 1913 } 1914 1915 if (uiOffset >= EEPROM_CALPARAM_START) { 1916 uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START); 1917 while (uiNumBytes) { 1918 if (uiNumBytes > BUFFER_4K) { 1919 wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K); 1920 uiNumBytes -= BUFFER_4K; 1921 uiIndex += BUFFER_4K; 1922 } else { 1923 wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes); 1924 uiNumBytes = 0; 1925 break; 1926 } 1927 } 1928 } else { 1929 if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) { 1930 ULONG ulBytesTobeSkipped = 0; 1931 PUCHAR pcBuffer = (PUCHAR)pBuffer; /* char pointer to take care of odd byte cases. */ 1932 uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset); 1933 ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset); 1934 uiOffset += (EEPROM_CALPARAM_START - uiOffset); 1935 while (uiNumBytes) { 1936 if (uiNumBytes > BUFFER_4K) { 1937 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K); 1938 uiNumBytes -= BUFFER_4K; 1939 uiIndex += BUFFER_4K; 1940 } else { 1941 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes); 1942 uiNumBytes = 0; 1943 break; 1944 } 1945 } 1946 } 1947 } 1948 /* restore the values. */ 1949 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 1950 } else if (Adapter->eNVMType == NVM_EEPROM) { 1951 Status = BeceemEEPROMBulkWrite(Adapter, 1952 (PUCHAR)pBuffer, 1953 uiOffset, 1954 uiNumBytes, 1955 bVerify); 1956 if (bVerify) 1957 Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes); 1958 } else { 1959 Status = -1; 1960 } 1961 return Status; 1962} 1963 1964/* 1965 * Procedure: BcmUpdateSectorSize 1966 * 1967 * Description: Updates the sector size to FLASH. 1968 * 1969 * Arguments: 1970 * Adapter - ptr to Adapter object instance 1971 * uiSectorSize - sector size 1972 * 1973 * Returns: 1974 * OSAL_STATUS_SUCCESS - if NVM write is successful. 1975 * <FAILURE> - if failed. 1976 */ 1977 1978int BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, unsigned int uiSectorSize) 1979{ 1980 int Status = -1; 1981 struct bcm_flash_cs_info sFlashCsInfo = {0}; 1982 unsigned int uiTemp = 0; 1983 unsigned int uiSectorSig = 0; 1984 unsigned int uiCurrentSectorSize = 0; 1985 unsigned int value; 1986 1987 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 1988 value = 0; 1989 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); 1990 1991 /* 1992 * Before updating the sector size in the reserved area, check if already present. 1993 */ 1994 BeceemFlashBulkRead(Adapter, (PUINT)&sFlashCsInfo, Adapter->ulFlashControlSectionStart, sizeof(sFlashCsInfo)); 1995 uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig); 1996 uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize); 1997 1998 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { 1999 if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) { 2000 if (uiSectorSize == uiCurrentSectorSize) { 2001 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash"); 2002 Status = STATUS_SUCCESS; 2003 goto Restore; 2004 } 2005 } 2006 } 2007 2008 if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) { 2009 sFlashCsInfo.FlashSectorSize = htonl(uiSectorSize); 2010 sFlashCsInfo.FlashSectorSizeSig = htonl(FLASH_SECTOR_SIZE_SIG); 2011 2012 Status = BeceemFlashBulkWrite(Adapter, 2013 (PUINT)&sFlashCsInfo, 2014 Adapter->ulFlashControlSectionStart, 2015 sizeof(sFlashCsInfo), 2016 TRUE); 2017 } 2018 2019Restore: 2020 /* restore the values. */ 2021 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 2022 2023 return Status; 2024} 2025 2026/* 2027 * Procedure: BcmGetFlashSectorSize 2028 * 2029 * Description: Finds the sector size of the FLASH. 2030 * 2031 * Arguments: 2032 * Adapter - ptr to Adapter object instance 2033 * 2034 * Returns: 2035 * unsigned int - sector size. 2036 * 2037 */ 2038 2039static unsigned int BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, unsigned int FlashSectorSizeSig, unsigned int FlashSectorSize) 2040{ 2041 unsigned int uiSectorSize = 0; 2042 unsigned int uiSectorSig = 0; 2043 2044 if (Adapter->bSectorSizeOverride && 2045 (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && 2046 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) { 2047 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; 2048 } else { 2049 uiSectorSig = FlashSectorSizeSig; 2050 2051 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) { 2052 uiSectorSize = FlashSectorSize; 2053 /* 2054 * If the sector size stored in the FLASH makes sense then use it. 2055 */ 2056 if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) { 2057 Adapter->uiSectorSize = uiSectorSize; 2058 } else if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && 2059 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) { 2060 /* No valid size in FLASH, check if Config file has it. */ 2061 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; 2062 } else { 2063 /* Init to Default, if none of the above works. */ 2064 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; 2065 } 2066 } else { 2067 if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE && 2068 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE) 2069 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG; 2070 else 2071 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE; 2072 } 2073 } 2074 2075 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x\n", Adapter->uiSectorSize); 2076 2077 return Adapter->uiSectorSize; 2078} 2079 2080/* 2081 * Procedure: BcmInitEEPROMQueues 2082 * 2083 * Description: Initialization of EEPROM queues. 2084 * 2085 * Arguments: 2086 * Adapter - ptr to Adapter object instance 2087 * 2088 * Returns: 2089 * <OSAL_STATUS_CODE> 2090 */ 2091 2092static int BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter) 2093{ 2094 unsigned int value = 0; 2095 /* CHIP Bug : Clear the Avail bits on the Read queue. The default 2096 * value on this register is supposed to be 0x00001102. 2097 * But we get 0x00001122. 2098 */ 2099 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n"); 2100 value = EEPROM_READ_DATA_AVAIL; 2101 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); 2102 2103 /* Flush the all the EEPROM queues. */ 2104 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Flushing the queues\n"); 2105 value = EEPROM_ALL_QUEUE_FLUSH; 2106 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); 2107 2108 value = 0; 2109 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value)); 2110 2111 /* Read the EEPROM Status Register. Just to see, no real purpose. */ 2112 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter)); 2113 2114 return STATUS_SUCCESS; 2115} /* BcmInitEEPROMQueues() */ 2116 2117/* 2118 * Procedure: BcmInitNVM 2119 * 2120 * Description: Initialization of NVM, EEPROM size,FLASH size, sector size etc. 2121 * 2122 * Arguments: 2123 * Adapter - ptr to Adapter object instance 2124 * 2125 * Returns: 2126 * <OSAL_STATUS_CODE> 2127 */ 2128 2129int BcmInitNVM(struct bcm_mini_adapter *ps_adapter) 2130{ 2131 BcmValidateNvmType(ps_adapter); 2132 BcmInitEEPROMQueues(ps_adapter); 2133 2134 if (ps_adapter->eNVMType == NVM_AUTODETECT) { 2135 ps_adapter->eNVMType = BcmGetNvmType(ps_adapter); 2136 if (ps_adapter->eNVMType == NVM_UNKNOWN) 2137 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n"); 2138 } else if (ps_adapter->eNVMType == NVM_FLASH) { 2139 BcmGetFlashCSInfo(ps_adapter); 2140 } 2141 2142 BcmGetNvmSize(ps_adapter); 2143 2144 return STATUS_SUCCESS; 2145} 2146 2147/* BcmGetNvmSize : set the EEPROM or flash size in Adapter. 2148 * 2149 * Input Parameter: 2150 * Adapter data structure 2151 * Return Value : 2152 * 0. means success; 2153 */ 2154 2155static int BcmGetNvmSize(struct bcm_mini_adapter *Adapter) 2156{ 2157 if (Adapter->eNVMType == NVM_EEPROM) 2158 Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter); 2159 else if (Adapter->eNVMType == NVM_FLASH) 2160 Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter); 2161 2162 return 0; 2163} 2164 2165/* 2166 * Procedure: BcmValidateNvm 2167 * 2168 * Description: Validates the NVM Type option selected against the device 2169 * 2170 * Arguments: 2171 * Adapter - ptr to Adapter object instance 2172 * 2173 * Returns: 2174 * <VOID> 2175 */ 2176 2177static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter) 2178{ 2179 /* 2180 * if forcing the FLASH through CFG file, we should ensure device really has a FLASH. 2181 * Accessing the FLASH address without the FLASH being present can cause hang/freeze etc. 2182 * So if NVM_FLASH is selected for older chipsets, change it to AUTODETECT where EEPROM is 1st choice. 2183 */ 2184 2185 if (Adapter->eNVMType == NVM_FLASH && 2186 Adapter->chip_id < 0xBECE3300) 2187 Adapter->eNVMType = NVM_AUTODETECT; 2188} 2189 2190/* 2191 * Procedure: BcmReadFlashRDID 2192 * 2193 * Description: Reads ID from Serial Flash 2194 * 2195 * Arguments: 2196 * Adapter - ptr to Adapter object instance 2197 * 2198 * Returns: 2199 * Flash ID 2200 */ 2201 2202static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter) 2203{ 2204 ULONG ulRDID = 0; 2205 unsigned int value; 2206 2207 /* 2208 * Read ID Instruction. 2209 */ 2210 value = (FLASH_CMD_READ_ID << 24); 2211 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)); 2212 2213 /* Delay */ 2214 udelay(10); 2215 2216 /* 2217 * Read SPI READQ REG. The output will be WWXXYYZZ. 2218 * The ID is 3Bytes long and is WWXXYY. ZZ needs to be Ignored. 2219 */ 2220 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulRDID, sizeof(ulRDID)); 2221 2222 return ulRDID >> 8; 2223} 2224 2225int BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) 2226{ 2227 if (!psAdapter) { 2228 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); 2229 return -EINVAL; 2230 } 2231 psAdapter->psFlashCSInfo = kzalloc(sizeof(struct bcm_flash_cs_info), GFP_KERNEL); 2232 if (psAdapter->psFlashCSInfo == NULL) { 2233 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x"); 2234 return -ENOMEM; 2235 } 2236 2237 psAdapter->psFlash2xCSInfo = kzalloc(sizeof(struct bcm_flash2x_cs_info), GFP_KERNEL); 2238 if (!psAdapter->psFlash2xCSInfo) { 2239 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x"); 2240 kfree(psAdapter->psFlashCSInfo); 2241 return -ENOMEM; 2242 } 2243 2244 psAdapter->psFlash2xVendorInfo = kzalloc(sizeof(struct bcm_flash2x_vendor_info), GFP_KERNEL); 2245 if (!psAdapter->psFlash2xVendorInfo) { 2246 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x"); 2247 kfree(psAdapter->psFlashCSInfo); 2248 kfree(psAdapter->psFlash2xCSInfo); 2249 return -ENOMEM; 2250 } 2251 2252 return STATUS_SUCCESS; 2253} 2254 2255int BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter) 2256{ 2257 if (!psAdapter) { 2258 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL"); 2259 return -EINVAL; 2260 } 2261 kfree(psAdapter->psFlashCSInfo); 2262 kfree(psAdapter->psFlash2xCSInfo); 2263 kfree(psAdapter->psFlash2xVendorInfo); 2264 return STATUS_SUCCESS; 2265} 2266 2267static int BcmDumpFlash2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo, struct bcm_mini_adapter *Adapter) 2268{ 2269 unsigned int Index = 0; 2270 2271 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "**********************FLASH2X CS Structure *******************"); 2272 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x", (psFlash2xCSInfo->MagicNumber)); 2273 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Major Version :%d", MAJOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); 2274 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Minor Version :%d", MINOR_VERSION(psFlash2xCSInfo->FlashLayoutVersion)); 2275 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ISOImageMajorVersion:0x%x", (psFlash2xCSInfo->ISOImageVersion)); 2276 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSIFirmwareMajorVersion :0x%x", (psFlash2xCSInfo->SCSIFirmwareVersion)); 2277 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart1ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage)); 2278 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForScsiFirmware :0x%x", (psFlash2xCSInfo->OffsetFromZeroForScsiFirmware)); 2279 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SizeOfScsiFirmware :0x%x", (psFlash2xCSInfo->SizeOfScsiFirmware)); 2280 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForPart2ISOImage :0x%x", (psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage)); 2281 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDStart)); 2282 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSDEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSDEnd)); 2283 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAStart)); 2284 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSAEnd :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSAEnd)); 2285 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionStart :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionStart)); 2286 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForControlSectionData :0x%x", (psFlash2xCSInfo->OffsetFromZeroForControlSectionData)); 2287 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CDLessInactivityTimeout :0x%x", (psFlash2xCSInfo->CDLessInactivityTimeout)); 2288 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "NewImageSignature :0x%x", (psFlash2xCSInfo->NewImageSignature)); 2289 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSizeSig :0x%x", (psFlash2xCSInfo->FlashSectorSizeSig)); 2290 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashSectorSize :0x%x", (psFlash2xCSInfo->FlashSectorSize)); 2291 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashWriteSupportSize :0x%x", (psFlash2xCSInfo->FlashWriteSupportSize)); 2292 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "TotalFlashSize :0x%X", (psFlash2xCSInfo->TotalFlashSize)); 2293 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashBaseAddr :0x%x", (psFlash2xCSInfo->FlashBaseAddr)); 2294 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FlashPartMaxSize :0x%x", (psFlash2xCSInfo->FlashPartMaxSize)); 2295 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "IsCDLessDeviceBootSig :0x%x", (psFlash2xCSInfo->IsCDLessDeviceBootSig)); 2296 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "MassStorageTimeout :0x%x", (psFlash2xCSInfo->MassStorageTimeout)); 2297 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1Start)); 2298 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part1End)); 2299 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2Start)); 2300 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part2End)); 2301 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3Start)); 2302 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage1Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage1Part3End)); 2303 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1Start)); 2304 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part1End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part1End)); 2305 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2Start)); 2306 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part2End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part2End)); 2307 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3Start :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3Start)); 2308 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetISOImage2Part3End :0x%x", (psFlash2xCSInfo->OffsetISOImage2Part3End)); 2309 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromDSDStartForDSDHeader :0x%x", (psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader)); 2310 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1Start)); 2311 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD1End)); 2312 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2Start)); 2313 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForDSD2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForDSD2End)); 2314 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1Start)); 2315 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA1End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA1End)); 2316 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2Start :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2Start)); 2317 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "OffsetFromZeroForVSA2End :0x%x", (psFlash2xCSInfo->OffsetFromZeroForVSA2End)); 2318 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector Access Bit Map is Defined as :"); 2319 2320 for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) 2321 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index, 2322 (psFlash2xCSInfo->SectorAccessBitMap[Index])); 2323 2324 return STATUS_SUCCESS; 2325} 2326 2327static int ConvertEndianOf2XCSStructure(struct bcm_flash2x_cs_info *psFlash2xCSInfo) 2328{ 2329 unsigned int Index = 0; 2330 2331 psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber); 2332 psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion); 2333 /* psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion); */ 2334 psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion); 2335 psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion); 2336 psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage); 2337 psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); 2338 psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware); 2339 psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart2ISOImage); 2340 psFlash2xCSInfo->OffsetFromZeroForDSDStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDStart); 2341 psFlash2xCSInfo->OffsetFromZeroForDSDEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSDEnd); 2342 psFlash2xCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAStart); 2343 psFlash2xCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSAEnd); 2344 psFlash2xCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); 2345 psFlash2xCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlash2xCSInfo->OffsetFromZeroForControlSectionData); 2346 psFlash2xCSInfo->CDLessInactivityTimeout = ntohl(psFlash2xCSInfo->CDLessInactivityTimeout); 2347 psFlash2xCSInfo->NewImageSignature = ntohl(psFlash2xCSInfo->NewImageSignature); 2348 psFlash2xCSInfo->FlashSectorSizeSig = ntohl(psFlash2xCSInfo->FlashSectorSizeSig); 2349 psFlash2xCSInfo->FlashSectorSize = ntohl(psFlash2xCSInfo->FlashSectorSize); 2350 psFlash2xCSInfo->FlashWriteSupportSize = ntohl(psFlash2xCSInfo->FlashWriteSupportSize); 2351 psFlash2xCSInfo->TotalFlashSize = ntohl(psFlash2xCSInfo->TotalFlashSize); 2352 psFlash2xCSInfo->FlashBaseAddr = ntohl(psFlash2xCSInfo->FlashBaseAddr); 2353 psFlash2xCSInfo->FlashPartMaxSize = ntohl(psFlash2xCSInfo->FlashPartMaxSize); 2354 psFlash2xCSInfo->IsCDLessDeviceBootSig = ntohl(psFlash2xCSInfo->IsCDLessDeviceBootSig); 2355 psFlash2xCSInfo->MassStorageTimeout = ntohl(psFlash2xCSInfo->MassStorageTimeout); 2356 psFlash2xCSInfo->OffsetISOImage1Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1Start); 2357 psFlash2xCSInfo->OffsetISOImage1Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part1End); 2358 psFlash2xCSInfo->OffsetISOImage1Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2Start); 2359 psFlash2xCSInfo->OffsetISOImage1Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part2End); 2360 psFlash2xCSInfo->OffsetISOImage1Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3Start); 2361 psFlash2xCSInfo->OffsetISOImage1Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage1Part3End); 2362 psFlash2xCSInfo->OffsetISOImage2Part1Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1Start); 2363 psFlash2xCSInfo->OffsetISOImage2Part1End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part1End); 2364 psFlash2xCSInfo->OffsetISOImage2Part2Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2Start); 2365 psFlash2xCSInfo->OffsetISOImage2Part2End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part2End); 2366 psFlash2xCSInfo->OffsetISOImage2Part3Start = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3Start); 2367 psFlash2xCSInfo->OffsetISOImage2Part3End = ntohl(psFlash2xCSInfo->OffsetISOImage2Part3End); 2368 psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader = ntohl(psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader); 2369 psFlash2xCSInfo->OffsetFromZeroForDSD1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1Start); 2370 psFlash2xCSInfo->OffsetFromZeroForDSD1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD1End); 2371 psFlash2xCSInfo->OffsetFromZeroForDSD2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2Start); 2372 psFlash2xCSInfo->OffsetFromZeroForDSD2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForDSD2End); 2373 psFlash2xCSInfo->OffsetFromZeroForVSA1Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1Start); 2374 psFlash2xCSInfo->OffsetFromZeroForVSA1End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA1End); 2375 psFlash2xCSInfo->OffsetFromZeroForVSA2Start = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2Start); 2376 psFlash2xCSInfo->OffsetFromZeroForVSA2End = ntohl(psFlash2xCSInfo->OffsetFromZeroForVSA2End); 2377 2378 for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++) 2379 psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]); 2380 2381 return STATUS_SUCCESS; 2382} 2383 2384static int ConvertEndianOfCSStructure(struct bcm_flash_cs_info *psFlashCSInfo) 2385{ 2386 /* unsigned int Index = 0; */ 2387 psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber); 2388 psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion); 2389 psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion); 2390 /* won't convert according to old assumption */ 2391 psFlashCSInfo->SCSIFirmwareVersion = (psFlashCSInfo->SCSIFirmwareVersion); 2392 psFlashCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart1ISOImage); 2393 psFlashCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlashCSInfo->OffsetFromZeroForScsiFirmware); 2394 psFlashCSInfo->SizeOfScsiFirmware = ntohl(psFlashCSInfo->SizeOfScsiFirmware); 2395 psFlashCSInfo->OffsetFromZeroForPart2ISOImage = ntohl(psFlashCSInfo->OffsetFromZeroForPart2ISOImage); 2396 psFlashCSInfo->OffsetFromZeroForCalibrationStart = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationStart); 2397 psFlashCSInfo->OffsetFromZeroForCalibrationEnd = ntohl(psFlashCSInfo->OffsetFromZeroForCalibrationEnd); 2398 psFlashCSInfo->OffsetFromZeroForVSAStart = ntohl(psFlashCSInfo->OffsetFromZeroForVSAStart); 2399 psFlashCSInfo->OffsetFromZeroForVSAEnd = ntohl(psFlashCSInfo->OffsetFromZeroForVSAEnd); 2400 psFlashCSInfo->OffsetFromZeroForControlSectionStart = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionStart); 2401 psFlashCSInfo->OffsetFromZeroForControlSectionData = ntohl(psFlashCSInfo->OffsetFromZeroForControlSectionData); 2402 psFlashCSInfo->CDLessInactivityTimeout = ntohl(psFlashCSInfo->CDLessInactivityTimeout); 2403 psFlashCSInfo->NewImageSignature = ntohl(psFlashCSInfo->NewImageSignature); 2404 psFlashCSInfo->FlashSectorSizeSig = ntohl(psFlashCSInfo->FlashSectorSizeSig); 2405 psFlashCSInfo->FlashSectorSize = ntohl(psFlashCSInfo->FlashSectorSize); 2406 psFlashCSInfo->FlashWriteSupportSize = ntohl(psFlashCSInfo->FlashWriteSupportSize); 2407 psFlashCSInfo->TotalFlashSize = ntohl(psFlashCSInfo->TotalFlashSize); 2408 psFlashCSInfo->FlashBaseAddr = ntohl(psFlashCSInfo->FlashBaseAddr); 2409 psFlashCSInfo->FlashPartMaxSize = ntohl(psFlashCSInfo->FlashPartMaxSize); 2410 psFlashCSInfo->IsCDLessDeviceBootSig = ntohl(psFlashCSInfo->IsCDLessDeviceBootSig); 2411 psFlashCSInfo->MassStorageTimeout = ntohl(psFlashCSInfo->MassStorageTimeout); 2412 2413 return STATUS_SUCCESS; 2414} 2415 2416static int IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section) 2417{ 2418 return (Adapter->uiVendorExtnFlag && 2419 (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) && 2420 (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS)); 2421} 2422 2423static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter) 2424{ 2425 B_UINT32 i = 0; 2426 unsigned int uiSizeSection = 0; 2427 2428 Adapter->uiVendorExtnFlag = FALSE; 2429 2430 for (i = 0; i < TOTAL_SECTIONS; i++) 2431 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS; 2432 2433 if (STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo)) 2434 return; 2435 2436 i = 0; 2437 while (i < TOTAL_SECTIONS) { 2438 if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) { 2439 i++; 2440 continue; 2441 } 2442 2443 Adapter->uiVendorExtnFlag = TRUE; 2444 uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd - 2445 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart); 2446 2447 switch (i) { 2448 case DSD0: 2449 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) && 2450 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) 2451 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = VENDOR_PTR_IN_CS; 2452 else 2453 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd = UNINIT_PTR_IN_CS; 2454 break; 2455 2456 case DSD1: 2457 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) && 2458 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) 2459 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = VENDOR_PTR_IN_CS; 2460 else 2461 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End = UNINIT_PTR_IN_CS; 2462 break; 2463 2464 case DSD2: 2465 if ((uiSizeSection >= (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header))) && 2466 (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart)) 2467 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = VENDOR_PTR_IN_CS; 2468 else 2469 Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End = UNINIT_PTR_IN_CS; 2470 break; 2471 case VSA0: 2472 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) 2473 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = VENDOR_PTR_IN_CS; 2474 else 2475 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd = UNINIT_PTR_IN_CS; 2476 break; 2477 2478 case VSA1: 2479 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) 2480 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = VENDOR_PTR_IN_CS; 2481 else 2482 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End = UNINIT_PTR_IN_CS; 2483 break; 2484 case VSA2: 2485 if (UNINIT_PTR_IN_CS != Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart) 2486 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = VENDOR_PTR_IN_CS; 2487 else 2488 Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start = Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End = UNINIT_PTR_IN_CS; 2489 break; 2490 2491 default: 2492 break; 2493 } 2494 i++; 2495 } 2496} 2497 2498/* 2499 * Procedure: BcmGetFlashCSInfo 2500 * 2501 * Description: Reads control structure and gets Cal section addresses. 2502 * 2503 * Arguments: 2504 * Adapter - ptr to Adapter object instance 2505 * 2506 * Returns: 2507 * <VOID> 2508 */ 2509 2510static int BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter) 2511{ 2512 /* struct bcm_flash_cs_info sFlashCsInfo = {0}; */ 2513 2514 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) 2515 unsigned int value; 2516 #endif 2517 2518 unsigned int uiFlashLayoutMajorVersion; 2519 Adapter->uiFlashLayoutMinorVersion = 0; 2520 Adapter->uiFlashLayoutMajorVersion = 0; 2521 Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR; 2522 2523 Adapter->uiFlashBaseAdd = 0; 2524 Adapter->ulFlashCalStart = 0; 2525 memset(Adapter->psFlashCSInfo, 0 , sizeof(struct bcm_flash_cs_info)); 2526 memset(Adapter->psFlash2xCSInfo, 0 , sizeof(struct bcm_flash2x_cs_info)); 2527 2528 if (!Adapter->bDDRInitDone) { 2529 value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; 2530 wrmalt(Adapter, 0xAF00A080, &value, sizeof(value)); 2531 } 2532 2533 /* Reading first 8 Bytes to get the Flash Layout 2534 * MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes) 2535 */ 2536 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8); 2537 2538 Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion); 2539 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion)); 2540 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion)); */ 2541 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber)); 2542 2543 if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) { 2544 uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); 2545 Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion)); 2546 } else { 2547 Adapter->uiFlashLayoutMinorVersion = 0; 2548 uiFlashLayoutMajorVersion = 0; 2549 } 2550 2551 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion); 2552 2553 if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) { 2554 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash_cs_info)); 2555 ConvertEndianOfCSStructure(Adapter->psFlashCSInfo); 2556 Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart); 2557 2558 if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) 2559 Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart; 2560 2561 if ((FLASH_CONTROL_STRUCT_SIGNATURE == (Adapter->psFlashCSInfo->MagicNumber)) && 2562 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlashCSInfo->SCSIFirmwareVersion)) && 2563 (FLASH_SECTOR_SIZE_SIG == (Adapter->psFlashCSInfo->FlashSectorSizeSig)) && 2564 (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) { 2565 Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize); 2566 Adapter->fpFlashWrite = flashByteWrite; 2567 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; 2568 } else { 2569 Adapter->ulFlashWriteSize = MAX_RW_SIZE; 2570 Adapter->fpFlashWrite = flashWrite; 2571 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; 2572 } 2573 2574 BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig), 2575 (Adapter->psFlashCSInfo->FlashSectorSize)); 2576 Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF; 2577 } else { 2578 if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL, 2579 Adapter->ulFlashControlSectionStart, sizeof(struct bcm_flash2x_cs_info))) { 2580 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n"); 2581 return STATUS_FAILURE; 2582 } 2583 2584 ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo); 2585 BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo, Adapter); 2586 if ((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) && 2587 (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) && 2588 (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) && 2589 (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) { 2590 Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize; 2591 Adapter->fpFlashWrite = flashByteWrite; 2592 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus; 2593 } else { 2594 Adapter->ulFlashWriteSize = MAX_RW_SIZE; 2595 Adapter->fpFlashWrite = flashWrite; 2596 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus; 2597 } 2598 2599 BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig, 2600 Adapter->psFlash2xCSInfo->FlashSectorSize); 2601 2602 UpdateVendorInfo(Adapter); 2603 2604 BcmGetActiveDSD(Adapter); 2605 BcmGetActiveISO(Adapter); 2606 Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF; 2607 Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart; 2608 } 2609 /* 2610 * Concerns: what if CS sector size does not match with this sector size ??? 2611 * what is the indication of AccessBitMap in CS in flash 2.x ???? 2612 */ 2613 Adapter->ulFlashID = BcmReadFlashRDID(Adapter); 2614 Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion; 2615 2616 return STATUS_SUCCESS; 2617} 2618 2619/* 2620 * Procedure: BcmGetNvmType 2621 * 2622 * Description: Finds the type of NVM used. 2623 * 2624 * Arguments: 2625 * Adapter - ptr to Adapter object instance 2626 * 2627 * Returns: 2628 * NVM_TYPE 2629 * 2630 */ 2631 2632static enum bcm_nvm_type BcmGetNvmType(struct bcm_mini_adapter *Adapter) 2633{ 2634 unsigned int uiData = 0; 2635 2636 BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4); 2637 if (uiData == BECM) 2638 return NVM_EEPROM; 2639 2640 /* 2641 * Read control struct and get cal addresses before accessing the flash 2642 */ 2643 BcmGetFlashCSInfo(Adapter); 2644 2645 BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4); 2646 if (uiData == BECM) 2647 return NVM_FLASH; 2648 2649 /* 2650 * even if there is no valid signature on EEPROM/FLASH find out if they really exist. 2651 * if exist select it. 2652 */ 2653 if (BcmGetEEPROMSize(Adapter)) 2654 return NVM_EEPROM; 2655 2656 /* TBD for Flash. */ 2657 return NVM_UNKNOWN; 2658} 2659 2660/* 2661 * BcmGetSectionValStartOffset - this will calculate the section's starting offset if section val is given 2662 * @Adapter : Drivers Private Data structure 2663 * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val 2664 * 2665 * Return value:- 2666 * On success it return the start offset of the provided section val 2667 * On Failure -returns STATUS_FAILURE 2668 */ 2669 2670int BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal) 2671{ 2672 /* 2673 * Considering all the section for which end offset can be calculated or directly given 2674 * in CS Structure. if matching case does not exist, return STATUS_FAILURE indicating section 2675 * endoffset can't be calculated or given in CS Structure. 2676 */ 2677 2678 int SectStartOffset = 0; 2679 2680 SectStartOffset = INVALID_OFFSET; 2681 2682 if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal)) 2683 return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart; 2684 2685 switch (eFlashSectionVal) { 2686 case ISO_IMAGE1: 2687 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && 2688 (IsNonCDLessDevice(Adapter) == FALSE)) 2689 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); 2690 break; 2691 case ISO_IMAGE2: 2692 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && 2693 (IsNonCDLessDevice(Adapter) == FALSE)) 2694 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); 2695 break; 2696 case DSD0: 2697 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) 2698 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart); 2699 break; 2700 case DSD1: 2701 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) 2702 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start); 2703 break; 2704 case DSD2: 2705 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) 2706 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start); 2707 break; 2708 case VSA0: 2709 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) 2710 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart); 2711 break; 2712 case VSA1: 2713 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) 2714 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start); 2715 break; 2716 case VSA2: 2717 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) 2718 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start); 2719 break; 2720 case SCSI: 2721 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) 2722 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware); 2723 break; 2724 case CONTROL_SECTION: 2725 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) 2726 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart); 2727 break; 2728 case ISO_IMAGE1_PART2: 2729 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start != UNINIT_PTR_IN_CS) 2730 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start); 2731 break; 2732 case ISO_IMAGE1_PART3: 2733 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start != UNINIT_PTR_IN_CS) 2734 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); 2735 break; 2736 case ISO_IMAGE2_PART2: 2737 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start != UNINIT_PTR_IN_CS) 2738 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start); 2739 break; 2740 case ISO_IMAGE2_PART3: 2741 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start != UNINIT_PTR_IN_CS) 2742 SectStartOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); 2743 break; 2744 default: 2745 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); 2746 SectStartOffset = INVALID_OFFSET; 2747 } 2748 2749 return SectStartOffset; 2750} 2751 2752/* 2753 * BcmGetSectionValEndOffset - this will calculate the section's Ending offset if section val is given 2754 * @Adapter : Drivers Private Data structure 2755 * @eFlashSectionVal : Flash secion value defined in enum bcm_flash2x_section_val 2756 * 2757 * Return value:- 2758 * On success it return the end offset of the provided section val 2759 * On Failure -returns STATUS_FAILURE 2760 */ 2761 2762int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) 2763{ 2764 int SectEndOffset = 0; 2765 2766 SectEndOffset = INVALID_OFFSET; 2767 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) 2768 return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd; 2769 2770 switch (eFlash2xSectionVal) { 2771 case ISO_IMAGE1: 2772 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End != UNINIT_PTR_IN_CS) && 2773 (IsNonCDLessDevice(Adapter) == FALSE)) 2774 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End); 2775 break; 2776 case ISO_IMAGE2: 2777 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End != UNINIT_PTR_IN_CS) && 2778 (IsNonCDLessDevice(Adapter) == FALSE)) 2779 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End); 2780 break; 2781 case DSD0: 2782 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd != UNINIT_PTR_IN_CS) 2783 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDEnd); 2784 break; 2785 case DSD1: 2786 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End != UNINIT_PTR_IN_CS) 2787 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1End); 2788 break; 2789 case DSD2: 2790 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End != UNINIT_PTR_IN_CS) 2791 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2End); 2792 break; 2793 case VSA0: 2794 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd != UNINIT_PTR_IN_CS) 2795 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAEnd); 2796 break; 2797 case VSA1: 2798 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End != UNINIT_PTR_IN_CS) 2799 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1End); 2800 break; 2801 case VSA2: 2802 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End != UNINIT_PTR_IN_CS) 2803 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2End); 2804 break; 2805 case SCSI: 2806 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) 2807 SectEndOffset = ((Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) + 2808 (Adapter->psFlash2xCSInfo->SizeOfScsiFirmware)); 2809 break; 2810 case CONTROL_SECTION: 2811 /* Not Clear So Putting failure. confirm and fix it. */ 2812 SectEndOffset = STATUS_FAILURE; 2813 break; 2814 case ISO_IMAGE1_PART2: 2815 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End != UNINIT_PTR_IN_CS) 2816 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End); 2817 break; 2818 case ISO_IMAGE1_PART3: 2819 if (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End != UNINIT_PTR_IN_CS) 2820 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End); 2821 break; 2822 case ISO_IMAGE2_PART2: 2823 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End != UNINIT_PTR_IN_CS) 2824 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End); 2825 break; 2826 case ISO_IMAGE2_PART3: 2827 if (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End != UNINIT_PTR_IN_CS) 2828 SectEndOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End); 2829 break; 2830 default: 2831 SectEndOffset = INVALID_OFFSET; 2832 } 2833 2834 return SectEndOffset ; 2835} 2836 2837/* 2838 * BcmFlash2xBulkRead:- Read API for Flash Map 2.x . 2839 * @Adapter :Driver Private Data Structure 2840 * @pBuffer : Buffer where data has to be put after reading 2841 * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val 2842 * @uiOffsetWithinSectionVal :- Offset with in provided section 2843 * @uiNumBytes : Number of Bytes for Read 2844 * 2845 * Return value:- 2846 * return true on success and STATUS_FAILURE on fail. 2847 */ 2848 2849int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, 2850 PUINT pBuffer, 2851 enum bcm_flash2x_section_val eFlash2xSectionVal, 2852 unsigned int uiOffsetWithinSectionVal, 2853 unsigned int uiNumBytes) 2854{ 2855 int Status = STATUS_SUCCESS; 2856 int SectionStartOffset = 0; 2857 unsigned int uiAbsoluteOffset = 0; 2858 unsigned int uiTemp = 0, value = 0; 2859 2860 if (!Adapter) { 2861 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); 2862 return -EINVAL; 2863 } 2864 if (Adapter->device_removed) { 2865 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); 2866 return -ENODEV; 2867 } 2868 2869 /* NO_SECTION_VAL means absolute offset is given. */ 2870 if (eFlash2xSectionVal == NO_SECTION_VAL) 2871 SectionStartOffset = 0; 2872 else 2873 SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); 2874 2875 if (SectionStartOffset == STATUS_FAILURE) { 2876 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash 2.x Map ", eFlash2xSectionVal); 2877 return -EINVAL; 2878 } 2879 2880 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) 2881 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes); 2882 2883 /* calculating the absolute offset from FLASH; */ 2884 uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset; 2885 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 2886 value = 0; 2887 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); 2888 Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes); 2889 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 2890 if (Status) { 2891 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status); 2892 return Status; 2893 } 2894 2895 return Status; 2896} 2897 2898/* 2899 * BcmFlash2xBulkWrite :-API for Writing on the Flash Map 2.x. 2900 * @Adapter :Driver Private Data Structure 2901 * @pBuffer : Buffer From where data has to taken for writing 2902 * @eFlashSectionVal :Flash Section Val defined in enum bcm_flash2x_section_val 2903 * @uiOffsetWithinSectionVal :- Offset with in provided section 2904 * @uiNumBytes : Number of Bytes for Write 2905 * 2906 * Return value:- 2907 * return true on success and STATUS_FAILURE on fail. 2908 * 2909 */ 2910 2911int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, 2912 PUINT pBuffer, 2913 enum bcm_flash2x_section_val eFlash2xSectVal, 2914 unsigned int uiOffset, 2915 unsigned int uiNumBytes, 2916 unsigned int bVerify) 2917{ 2918 int Status = STATUS_SUCCESS; 2919 unsigned int FlashSectValStartOffset = 0; 2920 unsigned int uiTemp = 0, value = 0; 2921 2922 if (!Adapter) { 2923 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL"); 2924 return -EINVAL; 2925 } 2926 2927 if (Adapter->device_removed) { 2928 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed"); 2929 return -ENODEV; 2930 } 2931 2932 /* NO_SECTION_VAL means absolute offset is given. */ 2933 if (eFlash2xSectVal == NO_SECTION_VAL) 2934 FlashSectValStartOffset = 0; 2935 else 2936 FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal); 2937 2938 if (FlashSectValStartOffset == STATUS_FAILURE) { 2939 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash Map 2.x", eFlash2xSectVal); 2940 return -EINVAL; 2941 } 2942 2943 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal)) 2944 return vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectVal, uiOffset, uiNumBytes, bVerify); 2945 2946 /* calculating the absolute offset from FLASH; */ 2947 uiOffset = uiOffset + FlashSectValStartOffset; 2948 2949 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 2950 value = 0; 2951 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); 2952 2953 Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify); 2954 2955 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 2956 if (Status) { 2957 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status); 2958 return Status; 2959 } 2960 2961 return Status; 2962} 2963 2964/* 2965 * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR 2966 * @Adapter :-Drivers private Data Structure 2967 * 2968 * Return Value:- 2969 * Return STATUS_SUCESS if get success in setting the right DSD else negaive error code 2970 * 2971 */ 2972 2973static int BcmGetActiveDSD(struct bcm_mini_adapter *Adapter) 2974{ 2975 enum bcm_flash2x_section_val uiHighestPriDSD = 0; 2976 2977 uiHighestPriDSD = getHighestPriDSD(Adapter); 2978 Adapter->eActiveDSD = uiHighestPriDSD; 2979 2980 if (DSD0 == uiHighestPriDSD) 2981 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; 2982 if (DSD1 == uiHighestPriDSD) 2983 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; 2984 if (DSD2 == uiHighestPriDSD) 2985 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; 2986 if (Adapter->eActiveDSD) 2987 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD); 2988 if (Adapter->eActiveDSD == 0) { 2989 /* if No DSD gets Active, Make Active the DSD with WR permission */ 2990 if (IsSectionWritable(Adapter, DSD2)) { 2991 Adapter->eActiveDSD = DSD2; 2992 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start; 2993 } else if (IsSectionWritable(Adapter, DSD1)) { 2994 Adapter->eActiveDSD = DSD1; 2995 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start; 2996 } else if (IsSectionWritable(Adapter, DSD0)) { 2997 Adapter->eActiveDSD = DSD0; 2998 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart; 2999 } 3000 } 3001 3002 return STATUS_SUCCESS; 3003} 3004 3005/* 3006 * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue 3007 * @Adapter : Driver private Data Structure 3008 * 3009 * Return Value:- 3010 * Sucsess:- STATUS_SUCESS 3011 * Failure- : negative erro code 3012 * 3013 */ 3014 3015static int BcmGetActiveISO(struct bcm_mini_adapter *Adapter) 3016{ 3017 int HighestPriISO = 0; 3018 3019 HighestPriISO = getHighestPriISO(Adapter); 3020 3021 Adapter->eActiveISO = HighestPriISO; 3022 if (Adapter->eActiveISO == ISO_IMAGE2) 3023 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start); 3024 else if (Adapter->eActiveISO == ISO_IMAGE1) 3025 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start); 3026 3027 if (Adapter->eActiveISO) 3028 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO); 3029 3030 return STATUS_SUCCESS; 3031} 3032 3033/* 3034 * IsOffsetWritable :- it will tell the access permission of the sector having passed offset 3035 * @Adapter : Drivers Private Data Structure 3036 * @uiOffset : Offset provided in the Flash 3037 * 3038 * Return Value:- 3039 * Success:-TRUE , offset is writable 3040 * Failure:-FALSE, offset is RO 3041 * 3042 */ 3043 3044B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, unsigned int uiOffset) 3045{ 3046 unsigned int uiSectorNum = 0; 3047 unsigned int uiWordOfSectorPermission = 0; 3048 unsigned int uiBitofSectorePermission = 0; 3049 B_UINT32 permissionBits = 0; 3050 3051 uiSectorNum = uiOffset/Adapter->uiSectorSize; 3052 3053 /* calculating the word having this Sector Access permission from SectorAccessBitMap Array */ 3054 uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16]; 3055 3056 /* calculating the bit index inside the word for this sector */ 3057 uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16); 3058 3059 /* Setting Access permission */ 3060 permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission); 3061 permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3; 3062 if (permissionBits == SECTOR_READWRITE_PERMISSION) 3063 return TRUE; 3064 else 3065 return FALSE; 3066} 3067 3068static int BcmDumpFlash2xSectionBitMap(struct bcm_flash2x_bitmap *psFlash2xBitMap) 3069{ 3070 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); 3071 3072 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "***************Flash 2.x Section Bitmap***************"); 3073 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE1 :0X%x", psFlash2xBitMap->ISO_IMAGE1); 3074 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO_IMAGE2 :0X%x", psFlash2xBitMap->ISO_IMAGE2); 3075 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD0 :0X%x", psFlash2xBitMap->DSD0); 3076 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD1 :0X%x", psFlash2xBitMap->DSD1); 3077 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD2 :0X%x", psFlash2xBitMap->DSD2); 3078 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA0 :0X%x", psFlash2xBitMap->VSA0); 3079 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA1 :0X%x", psFlash2xBitMap->VSA1); 3080 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "VSA2 :0X%x", psFlash2xBitMap->VSA2); 3081 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SCSI :0X%x", psFlash2xBitMap->SCSI); 3082 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "CONTROL_SECTION :0X%x", psFlash2xBitMap->CONTROL_SECTION); 3083 3084 return STATUS_SUCCESS; 3085} 3086 3087/* 3088 * BcmGetFlash2xSectionalBitMap :- It will provide the bit map of all the section present in Flash 3089 * 8bit has been assigned to every section. 3090 * bit[0] :Section present or not 3091 * bit[1] :section is valid or not 3092 * bit[2] : Secton is read only or has write permission too. 3093 * bit[3] : Active Section - 3094 * bit[7...4] = Reserved . 3095 * 3096 * @Adapter:-Driver private Data Structure 3097 * 3098 * Return value:- 3099 * Success:- STATUS_SUCESS 3100 * Failure:- negative error code 3101 */ 3102 3103int BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_bitmap *psFlash2xBitMap) 3104{ 3105 struct bcm_flash2x_cs_info *psFlash2xCSInfo = Adapter->psFlash2xCSInfo; 3106 enum bcm_flash2x_section_val uiHighestPriDSD = 0; 3107 enum bcm_flash2x_section_val uiHighestPriISO = 0; 3108 BOOLEAN SetActiveDSDDone = FALSE; 3109 BOOLEAN SetActiveISODone = FALSE; 3110 3111 /* For 1.x map all the section except DSD0 will be shown as not present 3112 * This part will be used by calibration tool to detect the number of DSD present in Flash. 3113 */ 3114 if (IsFlash2x(Adapter) == FALSE) { 3115 psFlash2xBitMap->ISO_IMAGE2 = 0; 3116 psFlash2xBitMap->ISO_IMAGE1 = 0; 3117 psFlash2xBitMap->DSD0 = FLASH2X_SECTION_VALID | FLASH2X_SECTION_ACT | FLASH2X_SECTION_PRESENT; /* 0xF; 0000(Reseved)1(Active)0(RW)1(valid)1(present) */ 3118 psFlash2xBitMap->DSD1 = 0; 3119 psFlash2xBitMap->DSD2 = 0; 3120 psFlash2xBitMap->VSA0 = 0; 3121 psFlash2xBitMap->VSA1 = 0; 3122 psFlash2xBitMap->VSA2 = 0; 3123 psFlash2xBitMap->CONTROL_SECTION = 0; 3124 psFlash2xBitMap->SCSI = 0; 3125 psFlash2xBitMap->Reserved0 = 0; 3126 psFlash2xBitMap->Reserved1 = 0; 3127 psFlash2xBitMap->Reserved2 = 0; 3128 3129 return STATUS_SUCCESS; 3130 } 3131 3132 uiHighestPriDSD = getHighestPriDSD(Adapter); 3133 uiHighestPriISO = getHighestPriISO(Adapter); 3134 3135 /* 3136 * IS0 IMAGE 2 3137 */ 3138 if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) { 3139 /* Setting the 0th Bit representing the Section is present or not. */ 3140 psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT; 3141 3142 if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER) 3143 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID; 3144 3145 /* Calculation for extrating the Access permission */ 3146 if (IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE) 3147 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO; 3148 3149 if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) { 3150 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT; 3151 SetActiveISODone = TRUE; 3152 } 3153 } 3154 3155 /* 3156 * IS0 IMAGE 1 3157 */ 3158 if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) { 3159 /* Setting the 0th Bit representing the Section is present or not. */ 3160 psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT; 3161 3162 if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER) 3163 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID; 3164 3165 /* Calculation for extrating the Access permission */ 3166 if (IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE) 3167 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO; 3168 3169 if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) { 3170 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT; 3171 SetActiveISODone = TRUE; 3172 } 3173 } 3174 3175 /* 3176 * DSD2 3177 */ 3178 if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) { 3179 /* Setting the 0th Bit representing the Section is present or not. */ 3180 psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT; 3181 3182 if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER) 3183 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID; 3184 3185 /* Calculation for extrating the Access permission */ 3186 if (IsSectionWritable(Adapter, DSD2) == FALSE) { 3187 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO; 3188 } else { 3189 /* Means section is writable */ 3190 if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) { 3191 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT; 3192 SetActiveDSDDone = TRUE; 3193 } 3194 } 3195 } 3196 3197 /* 3198 * DSD 1 3199 */ 3200 if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) { 3201 /* Setting the 0th Bit representing the Section is present or not. */ 3202 psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT; 3203 3204 if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER) 3205 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID; 3206 3207 /* Calculation for extrating the Access permission */ 3208 if (IsSectionWritable(Adapter, DSD1) == FALSE) { 3209 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO; 3210 } else { 3211 /* Means section is writable */ 3212 if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) { 3213 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT; 3214 SetActiveDSDDone = TRUE; 3215 } 3216 } 3217 } 3218 3219 /* 3220 * For DSD 0 3221 */ 3222 if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) { 3223 /* Setting the 0th Bit representing the Section is present or not. */ 3224 psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT; 3225 3226 if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER) 3227 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID; 3228 3229 /* Setting Access permission */ 3230 if (IsSectionWritable(Adapter, DSD0) == FALSE) { 3231 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO; 3232 } else { 3233 /* Means section is writable */ 3234 if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD0)) { 3235 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT; 3236 SetActiveDSDDone = TRUE; 3237 } 3238 } 3239 } 3240 3241 /* 3242 * VSA 0 3243 */ 3244 if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) { 3245 /* Setting the 0th Bit representing the Section is present or not. */ 3246 psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT; 3247 3248 /* Setting the Access Bit. Map is not defined hece setting it always valid */ 3249 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID; 3250 3251 /* Calculation for extrating the Access permission */ 3252 if (IsSectionWritable(Adapter, VSA0) == FALSE) 3253 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO; 3254 3255 /* By Default section is Active */ 3256 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT; 3257 } 3258 3259 /* 3260 * VSA 1 3261 */ 3262 if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) { 3263 /* Setting the 0th Bit representing the Section is present or not. */ 3264 psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT; 3265 3266 /* Setting the Access Bit. Map is not defined hece setting it always valid */ 3267 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID; 3268 3269 /* Checking For Access permission */ 3270 if (IsSectionWritable(Adapter, VSA1) == FALSE) 3271 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO; 3272 3273 /* By Default section is Active */ 3274 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT; 3275 } 3276 3277 /* 3278 * VSA 2 3279 */ 3280 if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) { 3281 /* Setting the 0th Bit representing the Section is present or not. */ 3282 psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT; 3283 3284 /* Setting the Access Bit. Map is not defined hece setting it always valid */ 3285 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID; 3286 3287 /* Checking For Access permission */ 3288 if (IsSectionWritable(Adapter, VSA2) == FALSE) 3289 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO; 3290 3291 /* By Default section is Active */ 3292 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT; 3293 } 3294 3295 /* 3296 * SCSI Section 3297 */ 3298 if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) { 3299 /* Setting the 0th Bit representing the Section is present or not. */ 3300 psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT; 3301 3302 /* Setting the Access Bit. Map is not defined hece setting it always valid */ 3303 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID; 3304 3305 /* Checking For Access permission */ 3306 if (IsSectionWritable(Adapter, SCSI) == FALSE) 3307 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO; 3308 3309 /* By Default section is Active */ 3310 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT; 3311 } 3312 3313 /* 3314 * Control Section 3315 */ 3316 if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) { 3317 /* Setting the 0th Bit representing the Section is present or not. */ 3318 psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT); 3319 3320 /* Setting the Access Bit. Map is not defined hece setting it always valid */ 3321 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID; 3322 3323 /* Checking For Access permission */ 3324 if (IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE) 3325 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO; 3326 3327 /* By Default section is Active */ 3328 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT; 3329 } 3330 3331 /* 3332 * For Reserved Sections 3333 */ 3334 psFlash2xBitMap->Reserved0 = 0; 3335 psFlash2xBitMap->Reserved0 = 0; 3336 psFlash2xBitMap->Reserved0 = 0; 3337 BcmDumpFlash2xSectionBitMap(psFlash2xBitMap); 3338 3339 return STATUS_SUCCESS; 3340} 3341 3342/* 3343 * BcmSetActiveSection :- Set Active section is used to make priority field highest over other 3344 * section of same type. 3345 * 3346 * @Adapater :- Bcm Driver Private Data Structure 3347 * @eFlash2xSectionVal :- Flash section val whose priority has to be made highest. 3348 * 3349 * Return Value:- Make the priorit highest else return erorr code 3350 * 3351 */ 3352 3353int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectVal) 3354{ 3355 unsigned int SectImagePriority = 0; 3356 int Status = STATUS_SUCCESS; 3357 3358 /* struct bcm_dsd_header sDSD = {0}; 3359 * struct bcm_iso_header sISO = {0}; 3360 */ 3361 int HighestPriDSD = 0 ; 3362 int HighestPriISO = 0; 3363 3364 Status = IsSectionWritable(Adapter, eFlash2xSectVal); 3365 if (Status != TRUE) { 3366 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal); 3367 return STATUS_FAILURE; 3368 } 3369 3370 Adapter->bHeaderChangeAllowed = TRUE; 3371 switch (eFlash2xSectVal) { 3372 case ISO_IMAGE1: 3373 case ISO_IMAGE2: 3374 if (ReadISOSignature(Adapter, eFlash2xSectVal) == ISO_IMAGE_MAGIC_NUMBER) { 3375 HighestPriISO = getHighestPriISO(Adapter); 3376 3377 if (HighestPriISO == eFlash2xSectVal) { 3378 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); 3379 Status = STATUS_SUCCESS; 3380 break; 3381 } 3382 3383 SectImagePriority = ReadISOPriority(Adapter, HighestPriISO) + 1; 3384 3385 if ((SectImagePriority <= 0) && IsSectionWritable(Adapter, HighestPriISO)) { 3386 /* This is a SPECIAL Case which will only happen if the current highest priority ISO has priority value = 0x7FFFFFFF. 3387 * We will write 1 to the current Highest priority ISO And then shall increase the priority of the requested ISO 3388 * by user 3389 */ 3390 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); 3391 SectImagePriority = htonl(0x1); 3392 Status = BcmFlash2xBulkWrite(Adapter, 3393 &SectImagePriority, 3394 HighestPriISO, 3395 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority), 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 Status = STATUS_FAILURE; 3401 break; 3402 } 3403 3404 HighestPriISO = getHighestPriISO(Adapter); 3405 3406 if (HighestPriISO == eFlash2xSectVal) { 3407 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given ISO<%x> already has highest priority", eFlash2xSectVal); 3408 Status = STATUS_SUCCESS; 3409 break; 3410 } 3411 3412 SectImagePriority = 2; 3413 } 3414 3415 SectImagePriority = htonl(SectImagePriority); 3416 3417 Status = BcmFlash2xBulkWrite(Adapter, 3418 &SectImagePriority, 3419 eFlash2xSectVal, 3420 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority), 3421 SIGNATURE_SIZE, 3422 TRUE); 3423 if (Status) { 3424 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); 3425 break; 3426 } 3427 } else { 3428 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); 3429 Status = STATUS_FAILURE; 3430 break; 3431 } 3432 break; 3433 case DSD0: 3434 case DSD1: 3435 case DSD2: 3436 if (ReadDSDSignature(Adapter, eFlash2xSectVal) == DSD_IMAGE_MAGIC_NUMBER) { 3437 HighestPriDSD = getHighestPriDSD(Adapter); 3438 if ((HighestPriDSD == eFlash2xSectVal)) { 3439 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given DSD<%x> already has highest priority", eFlash2xSectVal); 3440 Status = STATUS_SUCCESS; 3441 break; 3442 } 3443 3444 SectImagePriority = ReadDSDPriority(Adapter, HighestPriDSD) + 1; 3445 if (SectImagePriority <= 0) { 3446 /* This is a SPECIAL Case which will only happen if the current highest priority DSD has priority value = 0x7FFFFFFF. 3447 * We will write 1 to the current Highest priority DSD And then shall increase the priority of the requested DSD 3448 * by user 3449 */ 3450 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, NVM_RW, DBG_LVL_ALL, "SectImagePriority wraparound happened, eFlash2xSectVal: 0x%x\n", eFlash2xSectVal); 3451 SectImagePriority = htonl(0x1); 3452 3453 Status = BcmFlash2xBulkWrite(Adapter, 3454 &SectImagePriority, 3455 HighestPriDSD, 3456 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), 3457 SIGNATURE_SIZE, 3458 TRUE); 3459 if (Status) { 3460 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); 3461 break; 3462 } 3463 3464 HighestPriDSD = getHighestPriDSD(Adapter); 3465 3466 if ((HighestPriDSD == eFlash2xSectVal)) { 3467 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Made the DSD: %x highest by reducing priority of other\n", eFlash2xSectVal); 3468 Status = STATUS_SUCCESS; 3469 break; 3470 } 3471 3472 SectImagePriority = htonl(0x2); 3473 Status = BcmFlash2xBulkWrite(Adapter, 3474 &SectImagePriority, 3475 HighestPriDSD, 3476 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), 3477 SIGNATURE_SIZE, 3478 TRUE); 3479 if (Status) { 3480 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); 3481 break; 3482 } 3483 3484 HighestPriDSD = getHighestPriDSD(Adapter); 3485 if ((HighestPriDSD == eFlash2xSectVal)) { 3486 Status = STATUS_SUCCESS; 3487 break; 3488 } 3489 3490 SectImagePriority = 3; 3491 } 3492 SectImagePriority = htonl(SectImagePriority); 3493 Status = BcmFlash2xBulkWrite(Adapter, 3494 &SectImagePriority, 3495 eFlash2xSectVal, 3496 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), 3497 SIGNATURE_SIZE, 3498 TRUE); 3499 if (Status) { 3500 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly"); 3501 Status = STATUS_FAILURE; 3502 break; 3503 } 3504 } else { 3505 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority"); 3506 Status = STATUS_FAILURE; 3507 break; 3508 } 3509 break; 3510 case VSA0: 3511 case VSA1: 3512 case VSA2: 3513 /* Has to be decided */ 3514 break; 3515 default: 3516 Status = STATUS_FAILURE; 3517 break; 3518 } 3519 3520 Adapter->bHeaderChangeAllowed = FALSE; 3521 return Status; 3522} 3523 3524/* 3525 * BcmCopyISO - Used only for copying the ISO section 3526 * @Adapater :- Bcm Driver Private Data Structure 3527 * @sCopySectStrut :- Section copy structure 3528 * 3529 * Return value:- SUCCESS if copies successfully else negative error code 3530 * 3531 */ 3532 3533int BcmCopyISO(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_copy_section sCopySectStrut) 3534{ 3535 PCHAR Buff = NULL; 3536 enum bcm_flash2x_section_val eISOReadPart = 0, eISOWritePart = 0; 3537 unsigned int uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0; 3538 unsigned int uiTotalDataToCopy = 0; 3539 BOOLEAN IsThisHeaderSector = FALSE; 3540 unsigned int sigOffset = 0; 3541 unsigned int ISOLength = 0; 3542 unsigned int Status = STATUS_SUCCESS; 3543 unsigned int SigBuff[MAX_RW_SIZE]; 3544 unsigned int i = 0; 3545 3546 if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) { 3547 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); 3548 return STATUS_FAILURE; 3549 } 3550 3551 Status = BcmFlash2xBulkRead(Adapter, 3552 &ISOLength, 3553 sCopySectStrut.SrcSection, 3554 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageSize), 3555 4); 3556 if (Status) { 3557 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n"); 3558 return Status; 3559 } 3560 3561 ISOLength = htonl(ISOLength); 3562 if (ISOLength % Adapter->uiSectorSize) 3563 ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize); 3564 3565 sigOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber); 3566 3567 Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL); 3568 3569 if (!Buff) { 3570 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size"); 3571 return -ENOMEM; 3572 } 3573 3574 if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) { 3575 eISOReadPart = ISO_IMAGE1; 3576 eISOWritePart = ISO_IMAGE2; 3577 uiReadOffsetWithinPart = 0; 3578 uiWriteOffsetWithinPart = 0; 3579 3580 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - 3581 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) + 3582 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - 3583 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) + 3584 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - 3585 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); 3586 3587 if (uiTotalDataToCopy < ISOLength) { 3588 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); 3589 Status = STATUS_FAILURE; 3590 goto out; 3591 } 3592 3593 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - 3594 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) + 3595 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - 3596 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) + 3597 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - 3598 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); 3599 3600 if (uiTotalDataToCopy < ISOLength) { 3601 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); 3602 Status = STATUS_FAILURE; 3603 goto out; 3604 } 3605 3606 uiTotalDataToCopy = ISOLength; 3607 3608 CorruptISOSig(Adapter, ISO_IMAGE2); 3609 while (uiTotalDataToCopy) { 3610 if (uiTotalDataToCopy == Adapter->uiSectorSize) { 3611 /* Setting for write of first sector. First sector is assumed to be written in last */ 3612 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); 3613 eISOReadPart = ISO_IMAGE1; 3614 uiReadOffsetWithinPart = 0; 3615 eISOWritePart = ISO_IMAGE2; 3616 uiWriteOffsetWithinPart = 0; 3617 IsThisHeaderSector = TRUE; 3618 } else { 3619 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; 3620 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; 3621 3622 if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { 3623 eISOReadPart = ISO_IMAGE1_PART2; 3624 uiReadOffsetWithinPart = 0; 3625 } 3626 3627 if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { 3628 eISOReadPart = ISO_IMAGE1_PART3; 3629 uiReadOffsetWithinPart = 0; 3630 } 3631 3632 if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { 3633 eISOWritePart = ISO_IMAGE2_PART2; 3634 uiWriteOffsetWithinPart = 0; 3635 } 3636 3637 if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { 3638 eISOWritePart = ISO_IMAGE2_PART3; 3639 uiWriteOffsetWithinPart = 0; 3640 } 3641 } 3642 3643 Status = BcmFlash2xBulkRead(Adapter, 3644 (PUINT)Buff, 3645 eISOReadPart, 3646 uiReadOffsetWithinPart, 3647 Adapter->uiSectorSize); 3648 if (Status) { 3649 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); 3650 break; 3651 } 3652 3653 if (IsThisHeaderSector == TRUE) { 3654 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */ 3655 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); 3656 3657 for (i = 0; i < MAX_RW_SIZE; i++) 3658 *(Buff + sigOffset + i) = 0xFF; 3659 } 3660 Adapter->bHeaderChangeAllowed = TRUE; 3661 Status = BcmFlash2xBulkWrite(Adapter, 3662 (PUINT)Buff, 3663 eISOWritePart, 3664 uiWriteOffsetWithinPart, 3665 Adapter->uiSectorSize, 3666 TRUE); 3667 if (Status) { 3668 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); 3669 break; 3670 } 3671 3672 Adapter->bHeaderChangeAllowed = FALSE; 3673 if (IsThisHeaderSector == TRUE) { 3674 WriteToFlashWithoutSectorErase(Adapter, 3675 SigBuff, 3676 eISOWritePart, 3677 sigOffset, 3678 MAX_RW_SIZE); 3679 IsThisHeaderSector = FALSE; 3680 } 3681 /* subtracting the written Data */ 3682 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; 3683 } 3684 } 3685 3686 if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) { 3687 eISOReadPart = ISO_IMAGE2; 3688 eISOWritePart = ISO_IMAGE1; 3689 uiReadOffsetWithinPart = 0; 3690 uiWriteOffsetWithinPart = 0; 3691 3692 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - 3693 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start) + 3694 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End) - 3695 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start) + 3696 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3End) - 3697 (Adapter->psFlash2xCSInfo->OffsetISOImage2Part3Start); 3698 3699 if (uiTotalDataToCopy < ISOLength) { 3700 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature"); 3701 Status = STATUS_FAILURE; 3702 goto out; 3703 } 3704 3705 uiTotalDataToCopy = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - 3706 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start) + 3707 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End) - 3708 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start) + 3709 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3End) - 3710 (Adapter->psFlash2xCSInfo->OffsetISOImage1Part3Start); 3711 3712 if (uiTotalDataToCopy < ISOLength) { 3713 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size"); 3714 Status = STATUS_FAILURE; 3715 goto out; 3716 } 3717 3718 uiTotalDataToCopy = ISOLength; 3719 3720 CorruptISOSig(Adapter, ISO_IMAGE1); 3721 3722 while (uiTotalDataToCopy) { 3723 if (uiTotalDataToCopy == Adapter->uiSectorSize) { 3724 /* Setting for write of first sector. First sector is assumed to be written in last */ 3725 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector"); 3726 eISOReadPart = ISO_IMAGE2; 3727 uiReadOffsetWithinPart = 0; 3728 eISOWritePart = ISO_IMAGE1; 3729 uiWriteOffsetWithinPart = 0; 3730 IsThisHeaderSector = TRUE; 3731 } else { 3732 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize; 3733 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize; 3734 3735 if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) { 3736 eISOReadPart = ISO_IMAGE2_PART2; 3737 uiReadOffsetWithinPart = 0; 3738 } 3739 3740 if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) { 3741 eISOReadPart = ISO_IMAGE2_PART3; 3742 uiReadOffsetWithinPart = 0; 3743 } 3744 3745 if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) { 3746 eISOWritePart = ISO_IMAGE1_PART2; 3747 uiWriteOffsetWithinPart = 0; 3748 } 3749 3750 if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) { 3751 eISOWritePart = ISO_IMAGE1_PART3; 3752 uiWriteOffsetWithinPart = 0; 3753 } 3754 } 3755 3756 Status = BcmFlash2xBulkRead(Adapter, 3757 (PUINT)Buff, 3758 eISOReadPart, 3759 uiReadOffsetWithinPart, 3760 Adapter->uiSectorSize); 3761 if (Status) { 3762 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart); 3763 break; 3764 } 3765 3766 if (IsThisHeaderSector == TRUE) { 3767 /* If this is header sector write 0xFFFFFFFF at the sig time and in last write sig */ 3768 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE); 3769 3770 for (i = 0; i < MAX_RW_SIZE; i++) 3771 *(Buff + sigOffset + i) = 0xFF; 3772 } 3773 Adapter->bHeaderChangeAllowed = TRUE; 3774 Status = BcmFlash2xBulkWrite(Adapter, 3775 (PUINT)Buff, 3776 eISOWritePart, 3777 uiWriteOffsetWithinPart, 3778 Adapter->uiSectorSize, 3779 TRUE); 3780 if (Status) { 3781 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart); 3782 break; 3783 } 3784 3785 Adapter->bHeaderChangeAllowed = FALSE; 3786 if (IsThisHeaderSector == TRUE) { 3787 WriteToFlashWithoutSectorErase(Adapter, 3788 SigBuff, 3789 eISOWritePart, 3790 sigOffset, 3791 MAX_RW_SIZE); 3792 3793 IsThisHeaderSector = FALSE; 3794 } 3795 3796 /* subtracting the written Data */ 3797 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize; 3798 } 3799 } 3800out: 3801 kfree(Buff); 3802 3803 return Status; 3804} 3805 3806/* 3807 * BcmFlash2xCorruptSig : this API is used to corrupt the written sig in Bcm Header present in flash section. 3808 * It will corrupt the sig, if Section is writable, by making first bytes as zero. 3809 * @Adapater :- Bcm Driver Private Data Structure 3810 * @eFlash2xSectionVal :- Flash section val which has header 3811 * 3812 * Return Value :- 3813 * Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS 3814 * Failure :-Return negative error code 3815 */ 3816 3817int BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) 3818{ 3819 int Status = STATUS_SUCCESS; 3820 3821 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal); 3822 3823 if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) { 3824 Status = CorruptDSDSig(Adapter, eFlash2xSectionVal); 3825 } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) { 3826 Status = CorruptISOSig(Adapter, eFlash2xSectionVal); 3827 } else { 3828 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal); 3829 return STATUS_SUCCESS; 3830 } 3831 return Status; 3832} 3833 3834/* 3835 *BcmFlash2xWriteSig :-this API is used to Write the sig if requested Section has 3836 * header and Write Permission. 3837 * @Adapater :- Bcm Driver Private Data Structure 3838 * @eFlashSectionVal :- Flash section val which has header 3839 * 3840 * Return Value :- 3841 * Success :- If Section is present and writable write the sig and return STATUS_SUCCESS 3842 * Failure :-Return negative error code 3843 */ 3844 3845int BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlashSectionVal) 3846{ 3847 unsigned int uiSignature = 0; 3848 unsigned int uiOffset = 0; 3849 3850 /* struct bcm_dsd_header dsdHeader = {0}; */ 3851 if (Adapter->bSigCorrupted == FALSE) { 3852 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n"); 3853 return STATUS_SUCCESS; 3854 } 3855 3856 if (Adapter->bAllDSDWriteAllow == FALSE) { 3857 if (IsSectionWritable(Adapter, eFlashSectionVal) == FALSE) { 3858 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature"); 3859 return SECTOR_IS_NOT_WRITABLE; 3860 } 3861 } 3862 3863 if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) { 3864 uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER); 3865 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader; 3866 3867 uiOffset += FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber); 3868 3869 if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { 3870 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig"); 3871 return STATUS_FAILURE; 3872 } 3873 } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) { 3874 uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER); 3875 /* uiOffset = 0; */ 3876 uiOffset = FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber); 3877 if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) { 3878 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig"); 3879 return STATUS_FAILURE; 3880 } 3881 } else { 3882 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal); 3883 return STATUS_FAILURE; 3884 } 3885 3886 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature"); 3887 3888 Adapter->bHeaderChangeAllowed = TRUE; 3889 Adapter->bSigCorrupted = FALSE; 3890 BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE); 3891 Adapter->bHeaderChangeAllowed = FALSE; 3892 3893 return STATUS_SUCCESS; 3894} 3895 3896/* 3897 * validateFlash2xReadWrite :- This API is used to validate the user request for Read/Write. 3898 * if requested Bytes goes beyond the Requested section, it reports error. 3899 * @Adapater :- Bcm Driver Private Data Structure 3900 * @psFlash2xReadWrite :-Flash2x Read/write structure pointer 3901 * 3902 * Return values:-Return TRUE is request is valid else FALSE. 3903 */ 3904 3905int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2x_readwrite *psFlash2xReadWrite) 3906{ 3907 unsigned int uiNumOfBytes = 0; 3908 unsigned int uiSectStartOffset = 0; 3909 unsigned int uiSectEndOffset = 0; 3910 3911 uiNumOfBytes = psFlash2xReadWrite->numOfBytes; 3912 3913 if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) { 3914 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exixt in Flash", psFlash2xReadWrite->Section); 3915 return FALSE; 3916 } 3917 uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section); 3918 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Start offset :%x ,section :%d\n", uiSectStartOffset, psFlash2xReadWrite->Section); 3919 if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) { 3920 if (psFlash2xReadWrite->Section == ISO_IMAGE1) { 3921 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1) - 3922 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) + 3923 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART2) - 3924 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART2) + 3925 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE1_PART3) - 3926 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1_PART3); 3927 } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) { 3928 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2) - 3929 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2) + 3930 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART2) - 3931 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART2) + 3932 BcmGetSectionValEndOffset(Adapter, ISO_IMAGE2_PART3) - 3933 BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2_PART3); 3934 } 3935 3936 /* since this uiSectEndoffset is the size of iso Image. hence for calculating the virtual endoffset 3937 * it should be added in startoffset. so that check done in last of this function can be valued. 3938 */ 3939 uiSectEndOffset = uiSectStartOffset + uiSectEndOffset; 3940 3941 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset); 3942 } else 3943 uiSectEndOffset = BcmGetSectionValEndOffset(Adapter, psFlash2xReadWrite->Section); 3944 3945 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset); 3946 3947 /* Checking the boundary condition */ 3948 if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset) 3949 return TRUE; 3950 else { 3951 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); 3952 return FALSE; 3953 } 3954} 3955 3956/* 3957 * IsFlash2x :- check for Flash 2.x 3958 * Adapater :- Bcm Driver Private Data Structure 3959 * 3960 * Return value:- 3961 * return TRUE if flah2.x of hgher version else return false. 3962 */ 3963 3964int IsFlash2x(struct bcm_mini_adapter *Adapter) 3965{ 3966 if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER) 3967 return TRUE; 3968 else 3969 return FALSE; 3970} 3971 3972/* 3973 * GetFlashBaseAddr :- Calculate the Flash Base address 3974 * @Adapater :- Bcm Driver Private Data Structure 3975 * 3976 * Return Value:- 3977 * Success :- Base Address of the Flash 3978 */ 3979 3980static int GetFlashBaseAddr(struct bcm_mini_adapter *Adapter) 3981{ 3982 unsigned int uiBaseAddr = 0; 3983 3984 if (Adapter->bDDRInitDone) { 3985 /* 3986 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr 3987 * In case of Raw Read... use the default value 3988 */ 3989 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && 3990 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) 3991 uiBaseAddr = Adapter->uiFlashBaseAdd; 3992 else 3993 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT; 3994 } else { 3995 /* 3996 * For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr 3997 * In case of Raw Read... use the default value 3998 */ 3999 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) && 4000 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1))) 4001 uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; 4002 else 4003 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT; 4004 } 4005 4006 return uiBaseAddr; 4007} 4008 4009/* 4010 * BcmCopySection :- This API is used to copy the One section in another. Both section should 4011 * be contiuous and of same size. Hence this Will not be applicabe to copy ISO. 4012 * 4013 * @Adapater :- Bcm Driver Private Data Structure 4014 * @SrcSection :- Source section From where data has to be copied 4015 * @DstSection :- Destination section to which data has to be copied 4016 * @offset :- Offset from/to where data has to be copied from one section to another. 4017 * @numOfBytes :- number of byes that has to be copyed from one section to another at given offset. 4018 * in case of numofBytes equal zero complete section will be copied. 4019 * Return Values- 4020 * Success : Return STATUS_SUCCESS 4021 * Faillure :- return negative error code 4022 */ 4023 4024int BcmCopySection(struct bcm_mini_adapter *Adapter, 4025 enum bcm_flash2x_section_val SrcSection, 4026 enum bcm_flash2x_section_val DstSection, 4027 unsigned int offset, 4028 unsigned int numOfBytes) 4029{ 4030 unsigned int BuffSize = 0; 4031 unsigned int BytesToBeCopied = 0; 4032 PUCHAR pBuff = NULL; 4033 int Status = STATUS_SUCCESS; 4034 4035 if (SrcSection == DstSection) { 4036 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again"); 4037 return -EINVAL; 4038 } 4039 4040 if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) { 4041 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection"); 4042 return -EINVAL; 4043 } 4044 4045 if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) { 4046 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection"); 4047 return -EINVAL; 4048 } 4049 4050 /* if offset zero means have to copy complete secton */ 4051 if (numOfBytes == 0) { 4052 numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection) 4053 - BcmGetSectionValStartOffset(Adapter, SrcSection); 4054 4055 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes); 4056 } 4057 4058 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection) 4059 - BcmGetSectionValStartOffset(Adapter, SrcSection)) { 4060 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " Input parameters going beyond the section offS: %x numB: %x of Source Section\n", 4061 offset, numOfBytes); 4062 return -EINVAL; 4063 } 4064 4065 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection) 4066 - BcmGetSectionValStartOffset(Adapter, DstSection)) { 4067 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Input parameters going beyond the section offS: %x numB: %x of Destination Section\n", 4068 offset, numOfBytes); 4069 return -EINVAL; 4070 } 4071 4072 if (numOfBytes > Adapter->uiSectorSize) 4073 BuffSize = Adapter->uiSectorSize; 4074 else 4075 BuffSize = numOfBytes; 4076 4077 pBuff = kzalloc(BuffSize, GFP_KERNEL); 4078 if (!pBuff) { 4079 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. "); 4080 return -ENOMEM; 4081 } 4082 4083 BytesToBeCopied = Adapter->uiSectorSize; 4084 if (offset % Adapter->uiSectorSize) 4085 BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize); 4086 if (BytesToBeCopied > numOfBytes) 4087 BytesToBeCopied = numOfBytes; 4088 4089 Adapter->bHeaderChangeAllowed = TRUE; 4090 4091 do { 4092 Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied); 4093 if (Status) { 4094 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied); 4095 break; 4096 } 4097 Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, FALSE); 4098 if (Status) { 4099 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied); 4100 break; 4101 } 4102 offset = offset + BytesToBeCopied; 4103 numOfBytes = numOfBytes - BytesToBeCopied; 4104 if (numOfBytes) { 4105 if (numOfBytes > Adapter->uiSectorSize) 4106 BytesToBeCopied = Adapter->uiSectorSize; 4107 else 4108 BytesToBeCopied = numOfBytes; 4109 } 4110 } while (numOfBytes > 0); 4111 4112 kfree(pBuff); 4113 Adapter->bHeaderChangeAllowed = FALSE; 4114 4115 return Status; 4116} 4117 4118/* 4119 * SaveHeaderIfPresent :- This API is use to Protect the Header in case of Header Sector write 4120 * @Adapater :- Bcm Driver Private Data Structure 4121 * @pBuff :- Data buffer that has to be written in sector having the header map. 4122 * @uiOffset :- Flash offset that has to be written. 4123 * 4124 * Return value :- 4125 * Success :- On success return STATUS_SUCCESS 4126 * Faillure :- Return negative error code 4127 */ 4128 4129int SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, unsigned int uiOffset) 4130{ 4131 unsigned int offsetToProtect = 0, HeaderSizeToProtect = 0; 4132 BOOLEAN bHasHeader = FALSE; 4133 PUCHAR pTempBuff = NULL; 4134 unsigned int uiSectAlignAddr = 0; 4135 unsigned int sig = 0; 4136 4137 /* making the offset sector aligned */ 4138 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); 4139 4140 if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) || 4141 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) || 4142 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) { 4143 /* offset from the sector boundary having the header map */ 4144 offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize; 4145 HeaderSizeToProtect = sizeof(struct bcm_dsd_header); 4146 bHasHeader = TRUE; 4147 } 4148 4149 if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) || 4150 uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) { 4151 offsetToProtect = 0; 4152 HeaderSizeToProtect = sizeof(struct bcm_iso_header); 4153 bHasHeader = TRUE; 4154 } 4155 /* If Header is present overwrite passed buffer with this */ 4156 if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) { 4157 pTempBuff = kzalloc(HeaderSizeToProtect, GFP_KERNEL); 4158 if (!pTempBuff) { 4159 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed"); 4160 return -ENOMEM; 4161 } 4162 /* Read header */ 4163 BeceemFlashBulkRead(Adapter, (PUINT)pTempBuff, (uiSectAlignAddr + offsetToProtect), HeaderSizeToProtect); 4164 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pTempBuff, HeaderSizeToProtect); 4165 /* Replace Buffer content with Header */ 4166 memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect); 4167 4168 kfree(pTempBuff); 4169 } 4170 if (bHasHeader && Adapter->bSigCorrupted) { 4171 sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))); 4172 sig = ntohl(sig); 4173 if ((sig & 0xFF000000) != CORRUPTED_PATTERN) { 4174 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore"); 4175 Adapter->bSigCorrupted = FALSE; 4176 return STATUS_SUCCESS; 4177 } 4178 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " Corrupted sig is :%X", sig); 4179 *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber))) = htonl(DSD_IMAGE_MAGIC_NUMBER); 4180 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature in Header Write only"); 4181 Adapter->bSigCorrupted = FALSE; 4182 } 4183 4184 return STATUS_SUCCESS; 4185} 4186 4187/* 4188 * BcmDoChipSelect : This will selcet the appropriate chip for writing. 4189 * @Adapater :- Bcm Driver Private Data Structure 4190 * 4191 * OutPut:- 4192 * Select the Appropriate chip and retrn status Success 4193 */ 4194static int BcmDoChipSelect(struct bcm_mini_adapter *Adapter, unsigned int offset) 4195{ 4196 unsigned int FlashConfig = 0; 4197 int ChipNum = 0; 4198 unsigned int GPIOConfig = 0; 4199 unsigned int PartNum = 0; 4200 4201 ChipNum = offset / FLASH_PART_SIZE; 4202 4203 /* 4204 * Chip Select mapping to enable flash0. 4205 * To select flash 0, we have to OR with (0<<12). 4206 * ORing 0 will have no impact so not doing that part. 4207 * In future if Chip select value changes from 0 to non zero, 4208 * That needs be taken care with backward comaptibility. No worries for now. 4209 */ 4210 4211 /* 4212 * SelectedChip Variable is the selection that the host is 100% Sure the same as what the register will hold. This can be ONLY ensured 4213 * if the Chip doesn't goes to low power mode while the flash operation is in progress (NVMRdmWrmLock is taken) 4214 * Before every new Flash Write operation, we reset the variable. This is to ensure that after any wake-up from 4215 * power down modes (Idle mode/shutdown mode), the values in the register will be different. 4216 */ 4217 4218 if (Adapter->SelectedChip == ChipNum) 4219 return STATUS_SUCCESS; 4220 4221 /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum); */ 4222 Adapter->SelectedChip = ChipNum; 4223 4224 /* bit[13..12] will select the appropriate chip */ 4225 rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4); 4226 rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); 4227 { 4228 switch (ChipNum) { 4229 case 0: 4230 PartNum = 0; 4231 break; 4232 case 1: 4233 PartNum = 3; 4234 GPIOConfig |= (0x4 << CHIP_SELECT_BIT12); 4235 break; 4236 case 2: 4237 PartNum = 1; 4238 GPIOConfig |= (0x1 << CHIP_SELECT_BIT12); 4239 break; 4240 case 3: 4241 PartNum = 2; 4242 GPIOConfig |= (0x2 << CHIP_SELECT_BIT12); 4243 break; 4244 } 4245 } 4246 /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired, 4247 * nothing to do... can return immediately. 4248 * ASSUMPTION: FLASH_GPIO_CONFIG_REG will be in sync with FLASH_CONFIG_REG. 4249 * Even if the chip goes to low power mode, it should wake with values in each register in sync with each other. 4250 * These values are not written by host other than during CHIP_SELECT. 4251 */ 4252 if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3)) 4253 return STATUS_SUCCESS; 4254 4255 /* clearing the bit[13..12] */ 4256 FlashConfig &= 0xFFFFCFFF; 4257 FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); /* 00 */ 4258 4259 wrmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); 4260 udelay(100); 4261 4262 wrmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4); 4263 udelay(100); 4264 4265 return STATUS_SUCCESS; 4266} 4267 4268int ReadDSDSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd) 4269{ 4270 unsigned int uiDSDsig = 0; 4271 /* unsigned int sigoffsetInMap = 0; 4272 * struct bcm_dsd_header dsdHeader = {0}; 4273 */ 4274 4275 /* sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader; */ 4276 4277 if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) { 4278 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for DSDs"); 4279 return STATUS_FAILURE; 4280 } 4281 BcmFlash2xBulkRead(Adapter, 4282 &uiDSDsig, 4283 dsd, 4284 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImageMagicNumber), 4285 SIGNATURE_SIZE); 4286 4287 uiDSDsig = ntohl(uiDSDsig); 4288 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig); 4289 4290 return uiDSDsig; 4291} 4292 4293int ReadDSDPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val dsd) 4294{ 4295 /* unsigned int priOffsetInMap = 0 ; */ 4296 unsigned int uiDSDPri = STATUS_FAILURE; 4297 /* struct bcm_dsd_header dsdHeader = {0}; 4298 * priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader; 4299 */ 4300 if (IsSectionWritable(Adapter, dsd)) { 4301 if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) { 4302 BcmFlash2xBulkRead(Adapter, 4303 &uiDSDPri, 4304 dsd, 4305 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(struct bcm_dsd_header *, DSDImagePriority), 4306 4); 4307 4308 uiDSDPri = ntohl(uiDSDPri); 4309 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri); 4310 } 4311 } 4312 4313 return uiDSDPri; 4314} 4315 4316enum bcm_flash2x_section_val getHighestPriDSD(struct bcm_mini_adapter *Adapter) 4317{ 4318 int DSDHighestPri = STATUS_FAILURE; 4319 int DsdPri = 0; 4320 enum bcm_flash2x_section_val HighestPriDSD = 0; 4321 4322 if (IsSectionWritable(Adapter, DSD2)) { 4323 DSDHighestPri = ReadDSDPriority(Adapter, DSD2); 4324 HighestPriDSD = DSD2; 4325 } 4326 4327 if (IsSectionWritable(Adapter, DSD1)) { 4328 DsdPri = ReadDSDPriority(Adapter, DSD1); 4329 if (DSDHighestPri < DsdPri) { 4330 DSDHighestPri = DsdPri; 4331 HighestPriDSD = DSD1; 4332 } 4333 } 4334 4335 if (IsSectionWritable(Adapter, DSD0)) { 4336 DsdPri = ReadDSDPriority(Adapter, DSD0); 4337 if (DSDHighestPri < DsdPri) { 4338 DSDHighestPri = DsdPri; 4339 HighestPriDSD = DSD0; 4340 } 4341 } 4342 if (HighestPriDSD) 4343 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest DSD :%x , and its Pri :%x", HighestPriDSD, DSDHighestPri); 4344 4345 return HighestPriDSD; 4346} 4347 4348int ReadISOSignature(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso) 4349{ 4350 unsigned int uiISOsig = 0; 4351 /* unsigned int sigoffsetInMap = 0; 4352 * struct bcm_iso_header ISOHeader = {0}; 4353 * sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader; 4354 */ 4355 if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) { 4356 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "passed section value is not for ISOs"); 4357 return STATUS_FAILURE; 4358 } 4359 BcmFlash2xBulkRead(Adapter, 4360 &uiISOsig, 4361 iso, 4362 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImageMagicNumber), 4363 SIGNATURE_SIZE); 4364 4365 uiISOsig = ntohl(uiISOsig); 4366 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig); 4367 4368 return uiISOsig; 4369} 4370 4371int ReadISOPriority(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val iso) 4372{ 4373 unsigned int ISOPri = STATUS_FAILURE; 4374 if (IsSectionWritable(Adapter, iso)) { 4375 if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) { 4376 BcmFlash2xBulkRead(Adapter, 4377 &ISOPri, 4378 iso, 4379 0 + FIELD_OFFSET_IN_HEADER(struct bcm_iso_header *, ISOImagePriority), 4380 4); 4381 4382 ISOPri = ntohl(ISOPri); 4383 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri); 4384 } 4385 } 4386 4387 return ISOPri; 4388} 4389 4390enum bcm_flash2x_section_val getHighestPriISO(struct bcm_mini_adapter *Adapter) 4391{ 4392 int ISOHighestPri = STATUS_FAILURE; 4393 int ISOPri = 0; 4394 enum bcm_flash2x_section_val HighestPriISO = NO_SECTION_VAL; 4395 4396 if (IsSectionWritable(Adapter, ISO_IMAGE2)) { 4397 ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2); 4398 HighestPriISO = ISO_IMAGE2; 4399 } 4400 4401 if (IsSectionWritable(Adapter, ISO_IMAGE1)) { 4402 ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1); 4403 if (ISOHighestPri < ISOPri) { 4404 ISOHighestPri = ISOPri; 4405 HighestPriISO = ISO_IMAGE1; 4406 } 4407 } 4408 if (HighestPriISO) 4409 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Highest ISO :%x and its Pri :%x", HighestPriISO, ISOHighestPri); 4410 4411 return HighestPriISO; 4412} 4413 4414int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, 4415 PUINT pBuff, 4416 enum bcm_flash2x_section_val eFlash2xSectionVal, 4417 unsigned int uiOffset, 4418 unsigned int uiNumBytes) 4419{ 4420 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS) 4421 unsigned int uiTemp = 0, value = 0; 4422 unsigned int i = 0; 4423 unsigned int uiPartOffset = 0; 4424 #endif 4425 unsigned int uiStartOffset = 0; 4426 /* Adding section start address */ 4427 int Status = STATUS_SUCCESS; 4428 PUCHAR pcBuff = (PUCHAR)pBuff; 4429 4430 if (uiNumBytes % Adapter->ulFlashWriteSize) { 4431 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes); 4432 return STATUS_FAILURE; 4433 } 4434 4435 uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); 4436 4437 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal)) 4438 return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes); 4439 4440 uiOffset = uiOffset + uiStartOffset; 4441 4442 #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) 4443 Status = bcmflash_raw_writenoerase((uiOffset / FLASH_PART_SIZE), (uiOffset % FLASH_PART_SIZE), pcBuff, uiNumBytes); 4444 #else 4445 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 4446 value = 0; 4447 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value)); 4448 4449 Adapter->SelectedChip = RESET_CHIP_SELECT; 4450 BcmDoChipSelect(Adapter, uiOffset); 4451 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter); 4452 4453 for (i = 0 ; i < uiNumBytes; i += Adapter->ulFlashWriteSize) { 4454 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) 4455 Status = flashByteWrite(Adapter, uiPartOffset, pcBuff); 4456 else 4457 Status = flashWrite(Adapter, uiPartOffset, pcBuff); 4458 4459 if (Status != STATUS_SUCCESS) 4460 break; 4461 4462 pcBuff = pcBuff + Adapter->ulFlashWriteSize; 4463 uiPartOffset = uiPartOffset + Adapter->ulFlashWriteSize; 4464 } 4465 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp)); 4466 Adapter->SelectedChip = RESET_CHIP_SELECT; 4467 #endif 4468 4469 return Status; 4470} 4471 4472BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val section) 4473{ 4474 BOOLEAN SectionPresent = FALSE; 4475 4476 switch (section) { 4477 case ISO_IMAGE1: 4478 if ((Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start != UNINIT_PTR_IN_CS) && 4479 (IsNonCDLessDevice(Adapter) == FALSE)) 4480 SectionPresent = TRUE; 4481 break; 4482 case ISO_IMAGE2: 4483 if ((Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start != UNINIT_PTR_IN_CS) && 4484 (IsNonCDLessDevice(Adapter) == FALSE)) 4485 SectionPresent = TRUE; 4486 break; 4487 case DSD0: 4488 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart != UNINIT_PTR_IN_CS) 4489 SectionPresent = TRUE; 4490 break; 4491 case DSD1: 4492 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start != UNINIT_PTR_IN_CS) 4493 SectionPresent = TRUE; 4494 break; 4495 case DSD2: 4496 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start != UNINIT_PTR_IN_CS) 4497 SectionPresent = TRUE; 4498 break; 4499 case VSA0: 4500 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSAStart != UNINIT_PTR_IN_CS) 4501 SectionPresent = TRUE; 4502 break; 4503 case VSA1: 4504 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA1Start != UNINIT_PTR_IN_CS) 4505 SectionPresent = TRUE; 4506 break; 4507 case VSA2: 4508 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForVSA2Start != UNINIT_PTR_IN_CS) 4509 SectionPresent = TRUE; 4510 break; 4511 case SCSI: 4512 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForScsiFirmware != UNINIT_PTR_IN_CS) 4513 SectionPresent = TRUE; 4514 break; 4515 case CONTROL_SECTION: 4516 if (Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart != UNINIT_PTR_IN_CS) 4517 SectionPresent = TRUE; 4518 break; 4519 default: 4520 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Does not exist in Flash 2.x"); 4521 SectionPresent = FALSE; 4522 } 4523 4524 return SectionPresent; 4525} 4526 4527int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val Section) 4528{ 4529 int offset = STATUS_FAILURE; 4530 int Status = FALSE; 4531 4532 if (IsSectionExistInFlash(Adapter, Section) == FALSE) { 4533 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exixt", Section); 4534 return FALSE; 4535 } 4536 4537 offset = BcmGetSectionValStartOffset(Adapter, Section); 4538 if (offset == INVALID_OFFSET) { 4539 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exixt", Section); 4540 return FALSE; 4541 } 4542 4543 if (IsSectionExistInVendorInfo(Adapter, Section)) 4544 return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO); 4545 4546 Status = IsOffsetWritable(Adapter, offset); 4547 return Status; 4548} 4549 4550static int CorruptDSDSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) 4551{ 4552 PUCHAR pBuff = NULL; 4553 unsigned int sig = 0; 4554 unsigned int uiOffset = 0; 4555 unsigned int BlockStatus = 0; 4556 unsigned int uiSectAlignAddr = 0; 4557 4558 Adapter->bSigCorrupted = FALSE; 4559 if (Adapter->bAllDSDWriteAllow == FALSE) { 4560 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { 4561 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); 4562 return SECTOR_IS_NOT_WRITABLE; 4563 } 4564 } 4565 4566 pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL); 4567 if (!pBuff) { 4568 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); 4569 return -ENOMEM; 4570 } 4571 4572 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(struct bcm_dsd_header); 4573 uiOffset -= MAX_RW_SIZE; 4574 4575 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE); 4576 4577 sig = *((PUINT)(pBuff + 12)); 4578 sig = ntohl(sig); 4579 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE); 4580 /* Now corrupting the sig by corrupting 4th last Byte. */ 4581 *(pBuff + 12) = 0; 4582 4583 if (sig == DSD_IMAGE_MAGIC_NUMBER) { 4584 Adapter->bSigCorrupted = TRUE; 4585 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) { 4586 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); 4587 BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize); 4588 4589 WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal, 4590 (uiOffset + 12), BYTE_WRITE_SUPPORT); 4591 if (BlockStatus) { 4592 BcmRestoreBlockProtectStatus(Adapter, BlockStatus); 4593 BlockStatus = 0; 4594 } 4595 } else { 4596 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, 4597 uiOffset, MAX_RW_SIZE); 4598 } 4599 } else { 4600 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); 4601 kfree(pBuff); 4602 4603 return STATUS_FAILURE; 4604 } 4605 4606 kfree(pBuff); 4607 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature"); 4608 4609 return STATUS_SUCCESS; 4610} 4611 4612static int CorruptISOSig(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section_val eFlash2xSectionVal) 4613{ 4614 PUCHAR pBuff = NULL; 4615 unsigned int sig = 0; 4616 unsigned int uiOffset = 0; 4617 4618 Adapter->bSigCorrupted = FALSE; 4619 4620 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) { 4621 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature"); 4622 return SECTOR_IS_NOT_WRITABLE; 4623 } 4624 4625 pBuff = kzalloc(MAX_RW_SIZE, GFP_KERNEL); 4626 if (!pBuff) { 4627 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey"); 4628 return -ENOMEM; 4629 } 4630 4631 uiOffset = 0; 4632 4633 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE); 4634 4635 sig = *((PUINT)pBuff); 4636 sig = ntohl(sig); 4637 4638 /* corrupt signature */ 4639 *pBuff = 0; 4640 4641 if (sig == ISO_IMAGE_MAGIC_NUMBER) { 4642 Adapter->bSigCorrupted = TRUE; 4643 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal, 4644 uiOffset, Adapter->ulFlashWriteSize); 4645 } else { 4646 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header"); 4647 kfree(pBuff); 4648 4649 return STATUS_FAILURE; 4650 } 4651 4652 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature"); 4653 BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, pBuff, MAX_RW_SIZE); 4654 4655 kfree(pBuff); 4656 return STATUS_SUCCESS; 4657} 4658 4659BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter) 4660{ 4661 if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG) 4662 return TRUE; 4663 else 4664 return FALSE; 4665}