Linux Audio

Check our new training course

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