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