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