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