Loading...
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
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}