Staging: bcm: Properly format braces in nvm.c
[deliverable/linux.git] / drivers / staging / bcm / nvm.c
CommitLineData
f8942e07
SH
1#include "headers.h"
2
3#define DWORD unsigned int
9dd47ee7 4
2979460d
KM
5static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset);
6static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter);
7static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter);
8static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter);
9static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter);
10static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize);
11
12static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter);
13static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter);
14static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter);
15static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter);
16
17static INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
18
19static B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset);
20static INT IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section);
21static INT IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section);
22
23static INT ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd);
24static INT ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd);
25static INT ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso);
26static INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso);
27
28static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
29static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal);
30static INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiSectAlignAddr);
31static INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter, PUINT pBuff,
093abf11
KM
32 FLASH2X_SECTION_VAL eFlash2xSectionVal,
33 UINT uiOffset, UINT uiNumBytes);
2979460d
KM
34static FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter);
35static FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter);
9dd47ee7
SH
36
37static INT BeceemFlashBulkRead(
2979460d 38 struct bcm_mini_adapter *Adapter,
9dd47ee7
SH
39 PUINT pBuffer,
40 UINT uiOffset,
41 UINT uiNumBytes);
42
43static INT BeceemFlashBulkWrite(
2979460d 44 struct bcm_mini_adapter *Adapter,
9dd47ee7
SH
45 PUINT pBuffer,
46 UINT uiOffset,
47 UINT uiNumBytes,
48 BOOLEAN bVerify);
49
2979460d 50static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter);
9dd47ee7 51
093abf11 52static INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter, UINT dwAddress, UINT *pdwData, UINT dwNumData);
9dd47ee7 53
f8942e07
SH
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
093abf11 65static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter)
f8942e07
SH
66{
67 UCHAR uiData = 0;
093abf11 68 DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
f8942e07
SH
69 UINT uiStatus = 0;
70 UINT value = 0;
71 UINT value1 = 0;
72
73 /* Read the EEPROM status register */
093abf11
KM
74 value = EEPROM_READ_STATUS_REGISTER;
75 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
f8942e07 76
a2940b63 77 while (dwRetries != 0) {
093abf11
KM
78 value = 0;
79 uiStatus = 0;
41c7b7c0 80 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
a2940b63 81 if (Adapter->device_removed == TRUE) {
093abf11 82 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting....");
f8942e07
SH
83 break;
84 }
85
86 /* Wait for Avail bit to be set. */
a2940b63 87 if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) {
f8942e07
SH
88 /* Clear the Avail/Full bits - which ever is set. */
89 value = uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
093abf11 90 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
f8942e07 91
093abf11 92 value = 0;
41c7b7c0 93 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
f8942e07
SH
94 uiData = (UCHAR)value;
95
96 break;
97 }
98
093abf11 99 dwRetries--;
a2940b63 100 if (dwRetries == 0) {
093abf11
KM
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);
f8942e07
SH
104 return uiData;
105 }
093abf11 106 if (!(dwRetries%RETRIES_PER_DELAY))
f8942e07
SH
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
2979460d 127INT ReadBeceemEEPROMBulk(struct bcm_mini_adapter *Adapter,
093abf11
KM
128 DWORD dwAddress,
129 DWORD *pdwData,
130 DWORD dwNumWords)
f8942e07
SH
131{
132 DWORD dwIndex = 0;
093abf11 133 DWORD dwRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
f8942e07 134 UINT uiStatus = 0;
093abf11 135 UINT value = 0;
f8942e07
SH
136 UINT value1 = 0;
137 UCHAR *pvalue;
138
139 /* Flush the read and cmd queue. */
093abf11
KM
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));
f8942e07
SH
144
145 /* Clear the Avail/Full bits. */
093abf11
KM
146 value = (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL);
147 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
f8942e07 148
093abf11
KM
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));
f8942e07 151
a2940b63 152 while (dwRetries != 0) {
f8942e07 153 uiStatus = 0;
41c7b7c0 154 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
a2940b63 155 if (Adapter->device_removed == TRUE) {
093abf11 156 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got Removed.hence exiting from loop...");
f8942e07
SH
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 */
a2940b63
KM
163 if (dwNumWords == 4) {
164 if ((uiStatus & EEPROM_READ_DATA_FULL) != 0) {
f8942e07 165 /* Clear the Avail/Full bits - which ever is set. */
093abf11
KM
166 value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL));
167 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
f8942e07
SH
168 break;
169 }
a2940b63
KM
170 } else if (dwNumWords == 1) {
171 if ((uiStatus & EEPROM_READ_DATA_AVAIL) != 0) {
f8942e07
SH
172 /* We just got Avail and we have to read 32bits so we
173 * need this sleep for Cardbus kind of devices. */
093abf11
KM
174 if (Adapter->chip_id == 0xBECE0210)
175 udelay(800);
f8942e07
SH
176
177 /* Clear the Avail/Full bits - which ever is set. */
093abf11
KM
178 value = (uiStatus & (EEPROM_READ_DATA_AVAIL | EEPROM_READ_DATA_FULL));
179 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
f8942e07
SH
180 break;
181 }
182 }
183
184 uiStatus = 0;
185
186 dwRetries--;
a2940b63 187 if (dwRetries == 0) {
093abf11
KM
188 value = 0;
189 value1 = 0;
41c7b7c0
KM
190 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
191 rdmalt(Adapter, EEPROM_SPI_Q_STATUS_REG, &value1, sizeof(value1));
093abf11
KM
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);
f8942e07
SH
194 return STATUS_FAILURE;
195 }
093abf11
KM
196
197 if (!(dwRetries%RETRIES_PER_DELAY))
f8942e07
SH
198 msleep(1);
199 }
200
a2940b63 201 for (dwIndex = 0; dwIndex < dwNumWords; dwIndex++) {
f8942e07
SH
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
093abf11 205 value = 0;
41c7b7c0 206 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
f8942e07
SH
207
208 pvalue[0] = value;
209
210 value = 0;
41c7b7c0 211 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
f8942e07
SH
212
213 pvalue[1] = value;
214
093abf11 215 value = 0;
41c7b7c0 216 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
f8942e07
SH
217
218 pvalue[2] = value;
219
220 value = 0;
41c7b7c0 221 rdmalt(Adapter, EEPROM_READ_DATAQ_REG, &value, sizeof(value));
f8942e07
SH
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
2979460d 244INT ReadBeceemEEPROM(struct bcm_mini_adapter *Adapter,
093abf11
KM
245 DWORD uiOffset,
246 DWORD *pBuffer)
f8942e07 247{
093abf11 248 UINT uiData[8] = {0};
f8942e07
SH
249 UINT uiByteOffset = 0;
250 UINT uiTempOffset = 0;
251
093abf11 252 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, " ====> ");
f8942e07
SH
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. */
093abf11 261 if (uiByteOffset > 12)
f8942e07 262 ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4);
f8942e07 263
093abf11 264 memcpy((PUCHAR)pBuffer, (((PUCHAR)&uiData[0]) + uiByteOffset), 4);
f8942e07
SH
265
266 return STATUS_SUCCESS;
267} /* ReadBeceemEEPROM() */
268
2979460d 269INT ReadMacAddressFromNVM(struct bcm_mini_adapter *Adapter)
f8942e07 270{
4ea4f7a0
SH
271 INT Status;
272 unsigned char puMacAddr[6];
f8942e07
SH
273
274 Status = BeceemNVMRead(Adapter,
275 (PUINT)&puMacAddr[0],
276 INIT_PARAMS_1_MACADDRESS_ADDRESS,
277 MAC_ADDRESS_SIZE);
278
093abf11 279 if (Status == STATUS_SUCCESS)
4ea4f7a0 280 memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE);
f8942e07
SH
281
282 return Status;
f8942e07
SH
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:
25985edc 297// OSAL_STATUS_SUCCESS - if EEPROM read is successful.
f8942e07
SH
298// <FAILURE> - if failed.
299//-----------------------------------------------------------------------------
300
093abf11
KM
301INT BeceemEEPROMBulkRead(struct bcm_mini_adapter *Adapter,
302 PUINT pBuffer,
303 UINT uiOffset,
304 UINT uiNumBytes)
f8942e07 305{
093abf11
KM
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;
f8942e07
SH
313 PUCHAR pcBuff = (PUCHAR)pBuffer;
314
a2940b63 315 if (uiOffset % MAX_RW_SIZE && uiBytesRemaining) {
093abf11
KM
316 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
317 uiExtraBytes = uiOffset - uiTempOffset;
318 ReadBeceemEEPROMBulk(Adapter, uiTempOffset, (PUINT)&uiData[0], 4);
a2940b63 319 if (uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) {
093abf11 320 memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), MAX_RW_SIZE - uiExtraBytes);
f8942e07
SH
321 uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes);
322 uiIndex += (MAX_RW_SIZE - uiExtraBytes);
323 uiOffset += (MAX_RW_SIZE - uiExtraBytes);
a2940b63 324 } else {
093abf11 325 memcpy(pBuffer, (((PUCHAR)&uiData[0]) + uiExtraBytes), uiBytesRemaining);
f8942e07
SH
326 uiIndex += uiBytesRemaining;
327 uiOffset += uiBytesRemaining;
328 uiBytesRemaining = 0;
329 }
f8942e07
SH
330 }
331
a2940b63 332 while (uiBytesRemaining && uiFailureRetries != 128) {
093abf11 333 if (Adapter->device_removed)
f8942e07 334 return -1;
f8942e07 335
a2940b63 336 if (uiBytesRemaining >= MAX_RW_SIZE) {
f8942e07
SH
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 */
a2940b63 340 if (0 == ReadBeceemEEPROMBulk(Adapter, uiOffset, &uiData[0], 4)) {
093abf11 341 memcpy(pcBuff + uiIndex, &uiData[0], MAX_RW_SIZE);
f8942e07
SH
342 uiOffset += MAX_RW_SIZE;
343 uiBytesRemaining -= MAX_RW_SIZE;
344 uiIndex += MAX_RW_SIZE;
a2940b63 345 } else {
f8942e07 346 uiFailureRetries++;
093abf11 347 mdelay(3); //sleep for a while before retry...
f8942e07 348 }
a2940b63
KM
349 } else if (uiBytesRemaining >= 4) {
350 if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) {
093abf11 351 memcpy(pcBuff + uiIndex, &uiData[0], 4);
f8942e07
SH
352 uiOffset += 4;
353 uiBytesRemaining -= 4;
093abf11 354 uiIndex += 4;
a2940b63 355 } else {
f8942e07 356 uiFailureRetries++;
093abf11 357 mdelay(3); //sleep for a while before retry...
f8942e07 358 }
a2940b63
KM
359 } else {
360 // Handle the reads less than 4 bytes...
f8942e07
SH
361 PUCHAR pCharBuff = (PUCHAR)pBuffer;
362 pCharBuff += uiIndex;
a2940b63 363 if (0 == ReadBeceemEEPROM(Adapter, uiOffset, &uiData[0])) {
093abf11 364 memcpy(pCharBuff, &uiData[0], uiBytesRemaining); //copy only bytes requested.
f8942e07 365 uiBytesRemaining = 0;
a2940b63 366 } else {
f8942e07 367 uiFailureRetries++;
093abf11 368 mdelay(3); //sleep for a while before retry...
f8942e07
SH
369 }
370 }
f8942e07
SH
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:
25985edc 388// OSAL_STATUS_SUCCESS - if FLASH read is successful.
f8942e07
SH
389// <FAILURE> - if failed.
390//-----------------------------------------------------------------------------
391
093abf11
KM
392static INT BeceemFlashBulkRead(struct bcm_mini_adapter *Adapter,
393 PUINT pBuffer,
394 UINT uiOffset,
395 UINT uiNumBytes)
f8942e07
SH
396{
397 UINT uiIndex = 0;
398 UINT uiBytesToRead = uiNumBytes;
399 INT Status = 0;
400 UINT uiPartOffset = 0;
41c7b7c0 401 int bytes;
f8942e07 402
a2940b63 403 if (Adapter->device_removed) {
093abf11 404 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device Got Removed");
f8942e07
SH
405 return -ENODEV;
406 }
407
093abf11
KM
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
f8942e07
SH
414
415 Adapter->SelectedChip = RESET_CHIP_SELECT;
416
a2940b63 417 if (uiOffset % MAX_RW_SIZE) {
093abf11 418 BcmDoChipSelect(Adapter, uiOffset);
f8942e07
SH
419 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
420
093abf11
KM
421 uiBytesToRead = MAX_RW_SIZE - (uiOffset % MAX_RW_SIZE);
422 uiBytesToRead = MIN(uiNumBytes, uiBytesToRead);
f8942e07 423
093abf11 424 bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
41c7b7c0
KM
425 if (bytes < 0) {
426 Status = bytes;
f8942e07
SH
427 Adapter->SelectedChip = RESET_CHIP_SELECT;
428 return Status;
429 }
430
431 uiIndex += uiBytesToRead;
432 uiOffset += uiBytesToRead;
433 uiNumBytes -= uiBytesToRead;
434 }
435
a2940b63 436 while (uiNumBytes) {
093abf11 437 BcmDoChipSelect(Adapter, uiOffset);
f8942e07
SH
438 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
439
093abf11 440 uiBytesToRead = MIN(uiNumBytes, MAX_RW_SIZE);
f8942e07 441
093abf11 442 bytes = rdm(Adapter, uiPartOffset, (PCHAR)pBuffer + uiIndex, uiBytesToRead);
41c7b7c0
KM
443 if (bytes < 0) {
444 Status = bytes;
f8942e07
SH
445 break;
446 }
447
f8942e07
SH
448 uiIndex += uiBytesToRead;
449 uiOffset += uiBytesToRead;
450 uiNumBytes -= uiBytesToRead;
f8942e07
SH
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
2979460d 469static UINT BcmGetFlashSize(struct bcm_mini_adapter *Adapter)
f8942e07 470{
093abf11
KM
471 if (IsFlash2x(Adapter))
472 return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER));
f8942e07 473 else
093abf11 474 return 32 * 1024;
f8942e07
SH
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
2979460d 490static UINT BcmGetEEPROMSize(struct bcm_mini_adapter *Adapter)
f8942e07
SH
491{
492 UINT uiData = 0;
493 UINT uiIndex = 0;
494
093abf11
KM
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);
a2940b63
KM
504 if (uiData == BECM) {
505 for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) {
093abf11
KM
506 BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4);
507 if (uiData == BECM)
093abf11 508 return uiIndex * 1024;
f8942e07 509 }
a2940b63 510 } else {
093abf11
KM
511 //
512 // EEPROM may not be present or not programmed
513 //
514 uiData = 0xBABEFACE;
a2940b63 515 if (0 == BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&uiData, 0, 4, TRUE)) {
f8942e07 516 uiData = 0;
a2940b63 517 for (uiIndex = 2; uiIndex <= 256; uiIndex *= 2) {
093abf11
KM
518 BeceemEEPROMBulkRead(Adapter, &uiData, uiIndex * 1024, 4);
519 if (uiData == 0xBABEFACE)
093abf11 520 return uiIndex * 1024;
f8942e07
SH
521 }
522 }
f8942e07
SH
523 }
524 return 0;
525}
526
f8942e07
SH
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
2979460d 542static INT FlashSectorErase(struct bcm_mini_adapter *Adapter,
093abf11
KM
543 UINT addr,
544 UINT numOfSectors)
f8942e07
SH
545{
546 UINT iIndex = 0, iRetries = 0;
547 UINT uiStatus = 0;
548 UINT value;
41c7b7c0 549 int bytes;
f8942e07 550
a2940b63 551 for (iIndex = 0; iIndex < numOfSectors; iIndex++) {
f8942e07
SH
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
a2940b63 559 do {
f8942e07 560 value = (FLASH_CMD_STATUS_REG_READ << 24);
a2940b63 561 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 562 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
f8942e07
SH
563 return STATUS_FAILURE;
564 }
565
41c7b7c0
KM
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;
f8942e07
SH
571 }
572 iRetries++;
093abf11
KM
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.
f8942e07 576 msleep(10);
093abf11 577 } while ((uiStatus & 0x1) && (iRetries < 400));
f8942e07 578
a2940b63 579 if (uiStatus & 0x1) {
093abf11 580 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "iRetries crossing the limit of 80000\n");
f8942e07
SH
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
093abf11
KM
602static INT flashByteWrite(struct bcm_mini_adapter *Adapter,
603 UINT uiOffset,
604 PVOID pData)
f8942e07 605{
f8942e07
SH
606 UINT uiStatus = 0;
607 INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
f8942e07
SH
608 UINT value;
609 ULONG ulData = *(PUCHAR)pData;
41c7b7c0 610 int bytes;
093abf11
KM
611 //
612 // need not write 0xFF because write requires an erase and erase will
613 // make whole sector 0xFF.
614 //
f8942e07 615
093abf11 616 if (0xFF == ulData)
f8942e07 617 return STATUS_SUCCESS;
f8942e07 618
093abf11 619 // DumpDebug(NVM_RW,("flashWrite ====>\n"));
f8942e07 620 value = (FLASH_CMD_WRITE_ENABLE << 24);
a2940b63 621 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 622 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails");
f8942e07
SH
623 return STATUS_FAILURE;
624 }
093abf11 625
a2940b63 626 if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) {
093abf11 627 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails");
f8942e07
SH
628 return STATUS_FAILURE;
629 }
630 value = (0x02000000 | (uiOffset & 0xFFFFFF));
a2940b63 631 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 632 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails");
f8942e07
SH
633 return STATUS_FAILURE;
634 }
635
636 //__udelay(950);
637
a2940b63 638 do {
f8942e07 639 value = (FLASH_CMD_STATUS_REG_READ << 24);
a2940b63 640 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 641 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
f8942e07 642 return STATUS_FAILURE;
093abf11
KM
643 }
644 //__udelay(1);
41c7b7c0
KM
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;
f8942e07 650 }
093abf11
KM
651 iRetries--;
652 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
653 msleep(1);
f8942e07 654
093abf11 655 } while ((uiStatus & 0x1) && (iRetries > 0));
f8942e07 656
a2940b63 657 if (uiStatus & 0x1) {
093abf11
KM
658 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
659 return STATUS_FAILURE;
f8942e07
SH
660 }
661
662 return STATUS_SUCCESS;
663}
664
f8942e07
SH
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
093abf11
KM
679static INT flashWrite(struct bcm_mini_adapter *Adapter,
680 UINT uiOffset,
681 PVOID pData)
f8942e07
SH
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
f8942e07 689 UINT value;
093abf11 690 UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
41c7b7c0 691 int bytes;
093abf11
KM
692 //
693 // need not write 0xFFFFFFFF because write requires an erase and erase will
694 // make whole sector 0xFFFFFFFF.
695 //
082e889b 696 if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE))
f8942e07 697 return 0;
f8942e07
SH
698
699 value = (FLASH_CMD_WRITE_ENABLE << 24);
700
a2940b63 701 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 702 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails");
f8942e07
SH
703 return STATUS_FAILURE;
704 }
093abf11 705
a2940b63 706 if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) {
093abf11 707 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails...");
f8942e07
SH
708 return STATUS_FAILURE;
709 }
710
711 //__udelay(950);
a2940b63 712 do {
f8942e07 713 value = (FLASH_CMD_STATUS_REG_READ << 24);
a2940b63 714 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 715 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
f8942e07 716 return STATUS_FAILURE;
093abf11
KM
717 }
718 //__udelay(1);
41c7b7c0
KM
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;
f8942e07
SH
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
093abf11
KM
731 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
732 msleep(1);
733 } while ((uiStatus & 0x1) && (iRetries > 0));
f8942e07 734
a2940b63 735 if (uiStatus & 0x1) {
093abf11
KM
736 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
737 return STATUS_FAILURE;
f8942e07
SH
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//-----------------------------------------------------------------------------
093abf11
KM
756static INT flashByteWriteStatus(struct bcm_mini_adapter *Adapter,
757 UINT uiOffset,
758 PVOID pData)
f8942e07
SH
759{
760 UINT uiStatus = 0;
761 INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
762 ULONG ulData = *(PUCHAR)pData;
763 UINT value;
41c7b7c0 764 int bytes;
f8942e07 765
093abf11
KM
766 //
767 // need not write 0xFFFFFFFF because write requires an erase and erase will
768 // make whole sector 0xFFFFFFFF.
769 //
f8942e07 770
093abf11 771 if (0xFF == ulData)
f8942e07 772 return STATUS_SUCCESS;
f8942e07
SH
773
774 // DumpDebug(NVM_RW,("flashWrite ====>\n"));
775
776 value = (FLASH_CMD_WRITE_ENABLE << 24);
a2940b63 777 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 778 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write enable in FLASH_SPI_CMDQ_REG register fails");
f8942e07
SH
779 return STATUS_SUCCESS;
780 }
a2940b63 781 if (wrm(Adapter, FLASH_SPI_WRITEQ_REG, (PCHAR)&ulData, 4) < 0) {
093abf11 782 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "DATA Write on FLASH_SPI_WRITEQ_REG fails");
f8942e07
SH
783 return STATUS_FAILURE;
784 }
785 value = (0x02000000 | (uiOffset & 0xFFFFFF));
a2940b63 786 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 787 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programming of FLASH_SPI_CMDQ_REG fails");
f8942e07
SH
788 return STATUS_FAILURE;
789 }
790
093abf11 791 //msleep(1);
f8942e07 792
a2940b63 793 do {
f8942e07 794 value = (FLASH_CMD_STATUS_REG_READ << 24);
a2940b63 795 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 796 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
f8942e07
SH
797 return STATUS_FAILURE;
798 }
799 //__udelay(1);
41c7b7c0
KM
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;
f8942e07
SH
805 }
806
807 iRetries--;
093abf11
KM
808 if (iRetries && ((iRetries % FLASH_PER_RETRIES_DELAY) == 0))
809 msleep(1);
810
811 } while ((uiStatus & 0x1) && (iRetries > 0));
f8942e07 812
a2940b63 813 if (uiStatus & 0x1) {
093abf11
KM
814 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
815 return STATUS_FAILURE;
f8942e07
SH
816 }
817
818 return STATUS_SUCCESS;
f8942e07
SH
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
093abf11
KM
834static INT flashWriteStatus(struct bcm_mini_adapter *Adapter,
835 UINT uiOffset,
836 PVOID pData)
f8942e07
SH
837{
838 UINT uiStatus = 0;
839 INT iRetries = MAX_FLASH_RETRIES * FLASH_PER_RETRIES_DELAY; //3
840 //UINT uiReadBack = 0;
841 UINT value;
093abf11 842 UINT uiErasePattern[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
41c7b7c0 843 int bytes;
f8942e07 844
093abf11
KM
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))
f8942e07 850 return 0;
f8942e07
SH
851
852 value = (FLASH_CMD_WRITE_ENABLE << 24);
a2940b63 853 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 854 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write Enable of FLASH_SPI_CMDQ_REG fails");
f8942e07
SH
855 return STATUS_FAILURE;
856 }
093abf11 857
a2940b63 858 if (wrm(Adapter, uiOffset, (PCHAR)pData, MAX_RW_SIZE) < 0) {
093abf11 859 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Data write fails...");
f8942e07
SH
860 return STATUS_FAILURE;
861 }
093abf11 862 // __udelay(1);
f8942e07 863
a2940b63 864 do {
f8942e07 865 value = (FLASH_CMD_STATUS_REG_READ << 24);
a2940b63 866 if (wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value)) < 0) {
093abf11 867 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Programing of FLASH_SPI_CMDQ_REG fails");
f8942e07 868 return STATUS_FAILURE;
093abf11
KM
869 }
870 //__udelay(1);
41c7b7c0
KM
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;
f8942e07 876 }
093abf11
KM
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);
f8942e07 884
093abf11
KM
885 } while ((uiStatus & 0x1) && (iRetries > 0));
886
a2940b63 887 if (uiStatus & 0x1) {
093abf11
KM
888 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write fails even after checking status for 200 times.");
889 return STATUS_FAILURE;
f8942e07
SH
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
093abf11 908static VOID BcmRestoreBlockProtectStatus(struct bcm_mini_adapter *Adapter, ULONG ulWriteStatus)
f8942e07
SH
909{
910 UINT value;
093abf11 911 value = (FLASH_CMD_WRITE_ENABLE << 24);
f8942e07
SH
912 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
913
914 udelay(20);
093abf11 915 value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
f8942e07
SH
916 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
917 udelay(20);
918}
093abf11 919
f8942e07
SH
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//-----------------------------------------------------------------------------
093abf11
KM
932
933static ULONG BcmFlashUnProtectBlock(struct bcm_mini_adapter *Adapter, UINT uiOffset, UINT uiLength)
f8942e07 934{
093abf11
KM
935 ULONG ulStatus = 0;
936 ULONG ulWriteStatus = 0;
f8942e07 937 UINT value;
f8942e07 938
093abf11 939 uiOffset = uiOffset&0x000FFFFF;
f8942e07 940 //
093abf11 941 // Implemented only for 1MB Flash parts.
f8942e07 942 //
a2940b63 943 if (FLASH_PART_SST25VF080B == Adapter->ulFlashID) {
093abf11
KM
944 //
945 // Get Current BP status.
946 //
f8942e07
SH
947 value = (FLASH_CMD_STATUS_REG_READ << 24);
948 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
949 udelay(10);
093abf11
KM
950 //
951 // Read status will be WWXXYYZZ. We have to take only WW.
952 //
f8942e07
SH
953 rdmalt(Adapter, FLASH_SPI_READQ_REG, (PUINT)&ulStatus, sizeof(ulStatus));
954 ulStatus >>= 24;
955 ulWriteStatus = ulStatus;
093abf11
KM
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
a2940b63
KM
963 if (ulStatus) {
964 if ((uiOffset+uiLength) <= 0x80000) {
093abf11
KM
965 //
966 // Offset comes in lower half of 1MB. Protect the upper half.
967 // Clear BP1 and BP0 and set BP2.
968 //
f8942e07
SH
969 ulWriteStatus |= (0x4<<2);
970 ulWriteStatus &= ~(0x3<<2);
a2940b63 971 } else if ((uiOffset + uiLength) <= 0xC0000) {
093abf11
KM
972 //
973 // Offset comes below Upper 1/4. Upper 1/4 can be protected.
974 // Clear BP2 and set BP1 and BP0.
975 //
f8942e07
SH
976 ulWriteStatus |= (0x3<<2);
977 ulWriteStatus &= ~(0x1<<4);
a2940b63 978 } else if ((uiOffset + uiLength) <= 0xE0000) {
093abf11
KM
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);
a2940b63 985 } else if ((uiOffset + uiLength) <= 0xF0000) {
093abf11
KM
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);
a2940b63 992 } else {
093abf11
KM
993 //
994 // Unblock all.
995 // Clear BP2,BP1 and BP0.
996 //
997 ulWriteStatus &= ~(0x7<<2);
998 }
999
1000 value = (FLASH_CMD_WRITE_ENABLE << 24);
f8942e07
SH
1001 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1002 udelay(20);
093abf11 1003 value = (FLASH_CMD_STATUS_REG_WRITE << 24) | (ulWriteStatus << 16);
f8942e07
SH
1004 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
1005 udelay(20);
f8942e07 1006 }
f8942e07
SH
1007 }
1008 return ulStatus;
1009}
093abf11 1010
f8942e07
SH
1011//-----------------------------------------------------------------------------
1012// Procedure: BeceemFlashBulkWrite
1013//
1014// Description: Performs write to the flash
1015//
1016// Arguments:
1017// Adapter - ptr to Adapter object instance
093abf11 1018// pBuffer - Data to be written.
f8942e07
SH
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
093abf11
KM
1027static INT BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter,
1028 PUINT pBuffer,
1029 UINT uiOffset,
1030 UINT uiNumBytes,
1031 BOOLEAN bVerify)
f8942e07 1032{
093abf11
KM
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;
f8942e07 1061
082e889b 1062 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
093abf11 1063 if (NULL == pTempBuff)
f8942e07 1064 goto BeceemFlashBulkWrite_EXIT;
093abf11
KM
1065 //
1066 // check if the data to be written is overlapped across sectors
1067 //
a2940b63 1068 if (uiOffset+uiNumBytes < uiSectBoundary) {
f8942e07 1069 uiNumSectTobeRead = 1;
a2940b63 1070 } else {
093abf11
KM
1071 // Number of sectors = Last sector start address/First sector start address
1072 uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize;
1073 if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize)
f8942e07 1074 uiNumSectTobeRead++;
f8942e07 1075 }
093abf11 1076 // Check whether Requested sector is writable or not in case of flash2x write. But if write call is
f8942e07
SH
1077 // for DSD calibration, allow it without checking of sector permission
1078
a2940b63 1079 if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) {
f8942e07 1080 index = 0;
093abf11 1081 uiTemp = uiNumSectTobeRead;
a2940b63
KM
1082 while (uiTemp) {
1083 if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) {
093abf11
KM
1084 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%X> is not writable",
1085 (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
f8942e07
SH
1086 Status = SECTOR_IS_NOT_WRITABLE;
1087 goto BeceemFlashBulkWrite_EXIT;
093abf11
KM
1088 }
1089 uiTemp = uiTemp - 1;
1090 index = index + 1 ;
f8942e07
SH
1091 }
1092 }
f8942e07 1093 Adapter->SelectedChip = RESET_CHIP_SELECT;
a2940b63 1094 while (uiNumSectTobeRead) {
093abf11
KM
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));
f8942e07
SH
1097 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1098
093abf11 1099 BcmDoChipSelect(Adapter, uiSectAlignAddr);
f8942e07 1100
093abf11 1101 if (0 != BeceemFlashBulkRead(Adapter,
f8942e07
SH
1102 (PUINT)pTempBuff,
1103 uiOffsetFromSectStart,
a2940b63 1104 Adapter->uiSectorSize)) {
f8942e07
SH
1105 Status = -1;
1106 goto BeceemFlashBulkWrite_EXIT;
1107 }
1108
093abf11
KM
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));
f8942e07 1111
093abf11 1112 ulStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
f8942e07 1113
a2940b63 1114 if (uiNumSectTobeRead > 1) {
093abf11
KM
1115 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1116 pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)));
1117 uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
a2940b63 1118 } else {
093abf11 1119 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes);
f8942e07
SH
1120 }
1121
093abf11 1122 if (IsFlash2x(Adapter))
093abf11 1123 SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart);
f8942e07 1124
093abf11
KM
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));
f8942e07 1128
a2940b63
KM
1129 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) {
1130 if (Adapter->device_removed) {
f8942e07
SH
1131 Status = -1;
1132 goto BeceemFlashBulkWrite_EXIT;
1133 }
093abf11 1134
a2940b63 1135 if (STATUS_SUCCESS != (*Adapter->fpFlashWrite)(Adapter, uiPartOffset + uiIndex, (&pTempBuff[uiIndex]))) {
f8942e07
SH
1136 Status = -1;
1137 goto BeceemFlashBulkWrite_EXIT;
1138 }
1139 }
1140
093abf11
KM
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));
a2940b63
KM
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) {
f8942e07 1146 UINT uiReadIndex = 0;
a2940b63
KM
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])) {
f8942e07
SH
1150 Status = STATUS_FAILURE;
1151 goto BeceemFlashBulkWrite_EXIT;
1152 }
1153 }
1154 }
a2940b63
KM
1155 } else {
1156 if (memcmp(ucReadBk, &pTempBuff[uiIndex], MAX_RW_SIZE)) {
1157 if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset + uiIndex, &pTempBuff[uiIndex])) {
f8942e07
SH
1158 Status = STATUS_FAILURE;
1159 goto BeceemFlashBulkWrite_EXIT;
1160 }
1161 }
1162 }
1163 }
1164 }
093abf11
KM
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));
a2940b63 1167 if (ulStatus) {
093abf11 1168 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
f8942e07
SH
1169 ulStatus = 0;
1170 }
1171
1172 uiCurrSectOffsetAddr = 0;
1173 uiSectAlignAddr = uiSectBoundary;
1174 uiSectBoundary += Adapter->uiSectorSize;
1175 uiOffsetFromSectStart += Adapter->uiSectorSize;
1176 uiNumSectTobeRead--;
1177 }
093abf11
KM
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 //
1184BeceemFlashBulkWrite_EXIT :
1185 if (ulStatus)
093abf11 1186 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
093abf11 1187
082e889b 1188 kfree(pTempBuff);
f8942e07
SH
1189
1190 Adapter->SelectedChip = RESET_CHIP_SELECT;
1191 return Status;
1192}
1193
f8942e07
SH
1194//-----------------------------------------------------------------------------
1195// Procedure: BeceemFlashBulkWriteStatus
1196//
1197// Description: Writes to Flash. Checks the SPI status after each write.
1198//
1199// Arguments:
093abf11
KM
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.
f8942e07
SH
1205// Returns:
1206// OSAL_STATUS_CODE
1207//
1208//-----------------------------------------------------------------------------
1209
093abf11
KM
1210static INT BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter,
1211 PUINT pBuffer,
1212 UINT uiOffset,
1213 UINT uiNumBytes,
1214 BOOLEAN bVerify)
f8942e07 1215{
093abf11
KM
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;
f8942e07 1240
082e889b 1241 pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL);
093abf11 1242 if (NULL == pTempBuff)
f8942e07 1243 goto BeceemFlashBulkWriteStatus_EXIT;
082e889b 1244
093abf11
KM
1245 //
1246 // check if the data to be written is overlapped across sectors
1247 //
a2940b63 1248 if (uiOffset+uiNumBytes < uiSectBoundary) {
f8942e07 1249 uiNumSectTobeRead = 1;
a2940b63 1250 } else {
093abf11
KM
1251 // Number of sectors = Last sector start address/First sector start address
1252 uiNumSectTobeRead = (uiCurrSectOffsetAddr + uiNumBytes) / Adapter->uiSectorSize;
1253 if ((uiCurrSectOffsetAddr + uiNumBytes)%Adapter->uiSectorSize)
f8942e07 1254 uiNumSectTobeRead++;
f8942e07
SH
1255 }
1256
a2940b63 1257 if (IsFlash2x(Adapter) && (Adapter->bAllDSDWriteAllow == FALSE)) {
f8942e07 1258 index = 0;
093abf11 1259 uiTemp = uiNumSectTobeRead;
a2940b63
KM
1260 while (uiTemp) {
1261 if (IsOffsetWritable(Adapter, uiOffsetFromSectStart + index * Adapter->uiSectorSize) == FALSE) {
093abf11
KM
1262 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Sector Starting at offset <0X%x> is not writable",
1263 (uiOffsetFromSectStart + index * Adapter->uiSectorSize));
f8942e07
SH
1264 Status = SECTOR_IS_NOT_WRITABLE;
1265 goto BeceemFlashBulkWriteStatus_EXIT;
093abf11
KM
1266 }
1267 uiTemp = uiTemp - 1;
1268 index = index + 1 ;
f8942e07
SH
1269 }
1270 }
1271
1272 Adapter->SelectedChip = RESET_CHIP_SELECT;
a2940b63 1273 while (uiNumSectTobeRead) {
f8942e07
SH
1274 uiPartOffset = (uiSectAlignAddr & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
1275
093abf11
KM
1276 BcmDoChipSelect(Adapter, uiSectAlignAddr);
1277 if (0 != BeceemFlashBulkRead(Adapter,
f8942e07
SH
1278 (PUINT)pTempBuff,
1279 uiOffsetFromSectStart,
a2940b63 1280 Adapter->uiSectorSize)) {
f8942e07
SH
1281 Status = -1;
1282 goto BeceemFlashBulkWriteStatus_EXIT;
1283 }
1284
093abf11 1285 ulStatus = BcmFlashUnProtectBlock(Adapter, uiOffsetFromSectStart, Adapter->uiSectorSize);
f8942e07 1286
a2940b63 1287 if (uiNumSectTobeRead > 1) {
093abf11
KM
1288 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
1289 pcBuffer += ((uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr)));
1290 uiNumBytes -= (uiSectBoundary - (uiSectAlignAddr + uiCurrSectOffsetAddr));
a2940b63 1291 } else {
093abf11 1292 memcpy(&pTempBuff[uiCurrSectOffsetAddr], pcBuffer, uiNumBytes);
f8942e07
SH
1293 }
1294
093abf11 1295 if (IsFlash2x(Adapter))
093abf11 1296 SaveHeaderIfPresent(Adapter, (PUCHAR)pTempBuff, uiOffsetFromSectStart);
f8942e07 1297
093abf11 1298 FlashSectorErase(Adapter, uiPartOffset, 1);
f8942e07 1299
a2940b63
KM
1300 for (uiIndex = 0; uiIndex < Adapter->uiSectorSize; uiIndex += Adapter->ulFlashWriteSize) {
1301 if (Adapter->device_removed) {
f8942e07
SH
1302 Status = -1;
1303 goto BeceemFlashBulkWriteStatus_EXIT;
1304 }
1305
a2940b63 1306 if (STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter, uiPartOffset+uiIndex, &pTempBuff[uiIndex])) {
f8942e07
SH
1307 Status = -1;
1308 goto BeceemFlashBulkWriteStatus_EXIT;
1309 }
1310 }
1311
a2940b63
KM
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)) {
f8942e07
SH
1316 Status = STATUS_FAILURE;
1317 goto BeceemFlashBulkWriteStatus_EXIT;
1318 }
f8942e07 1319 }
f8942e07
SH
1320 }
1321 }
1322
a2940b63 1323 if (ulStatus) {
093abf11 1324 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
f8942e07
SH
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//
093abf11
KM
1337BeceemFlashBulkWriteStatus_EXIT :
1338 if (ulStatus)
093abf11 1339 BcmRestoreBlockProtectStatus(Adapter, ulStatus);
082e889b
SH
1340
1341 kfree(pTempBuff);
f8942e07
SH
1342 Adapter->SelectedChip = RESET_CHIP_SELECT;
1343 return Status;
f8942e07
SH
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
2979460d 1358INT PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter)
f8942e07 1359{
082e889b 1360 PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL);
f8942e07
SH
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;
093abf11
KM
1368
1369 if (pBuff == NULL)
f8942e07 1370 return -1;
f8942e07 1371
a2940b63 1372 if (0 != BeceemEEPROMBulkRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) {
082e889b 1373 kfree(pBuff);
f8942e07
SH
1374 return -1;
1375 }
1376
1377 uiEepromSize >>= 16;
a2940b63 1378 if (uiEepromSize > 1024 * 1024) {
082e889b 1379 kfree(pBuff);
f8942e07
SH
1380 return -1;
1381 }
1382
093abf11 1383 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
f8942e07 1384
a2940b63
KM
1385 while (uiBytesToCopy) {
1386 if (0 != BeceemEEPROMBulkRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiBytesToCopy)) {
f8942e07
SH
1387 Status = -1;
1388 break;
1389 }
093abf11 1390 wrm(Adapter, uiMemoryLoc, (PCHAR)(((PULONG)pBuff) + uiIndex), uiBytesToCopy);
f8942e07
SH
1391 uiMemoryLoc += uiBytesToCopy;
1392 uiEepromSize -= uiBytesToCopy;
1393 uiCalStartAddr += uiBytesToCopy;
093abf11
KM
1394 uiIndex += uiBytesToCopy / 4;
1395 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
f8942e07
SH
1396
1397 }
1398 value = 0xbeadbead;
093abf11 1399 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
f8942e07 1400 value = 0xbeadbead;
093abf11 1401 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
082e889b 1402 kfree(pBuff);
f8942e07
SH
1403
1404 return Status;
f8942e07
SH
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
2979460d 1419INT PropagateCalParamsFromFlashToMemory(struct bcm_mini_adapter *Adapter)
f8942e07
SH
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;
093abf11
KM
1429
1430 //
1431 // Write the signature first. This will ensure firmware does not access EEPROM.
1432 //
f8942e07
SH
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
093abf11 1438 if (0 != BeceemNVMRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4))
f8942e07 1439 return -1;
a2940b63 1440
f8942e07
SH
1441 uiEepromSize = ntohl(uiEepromSize);
1442 uiEepromSize >>= 16;
1443
093abf11
KM
1444 //
1445 // subtract the auto init section size
1446 //
f8942e07
SH
1447 uiEepromSize -= EEPROM_CALPARAM_START;
1448
093abf11 1449 if (uiEepromSize > 1024 * 1024)
f8942e07 1450 return -1;
f8942e07 1451
082e889b 1452 pBuff = kmalloc(uiEepromSize, GFP_KERNEL);
093abf11 1453 if (pBuff == NULL)
f8942e07 1454 return -1;
f8942e07 1455
a2940b63 1456 if (0 != BeceemNVMRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiEepromSize)) {
082e889b 1457 kfree(pBuff);
f8942e07
SH
1458 return -1;
1459 }
1460
1461 pPtr = pBuff;
1462
093abf11 1463 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
f8942e07 1464
a2940b63 1465 while (uiBytesToCopy) {
093abf11 1466 Status = wrm(Adapter, uiMemoryLoc, (PCHAR)pPtr, uiBytesToCopy);
a2940b63 1467 if (Status) {
093abf11 1468 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed with status :%d", Status);
f8942e07
SH
1469 break;
1470 }
1471
1472 pPtr += uiBytesToCopy;
1473 uiEepromSize -= uiBytesToCopy;
1474 uiMemoryLoc += uiBytesToCopy;
093abf11 1475 uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize);
f8942e07
SH
1476 }
1477
082e889b 1478 kfree(pBuff);
f8942e07 1479 return Status;
f8942e07
SH
1480}
1481
1482//-----------------------------------------------------------------------------
1483// Procedure: BeceemEEPROMReadBackandVerify
1484//
1485// Description: Read back the data written and verifies.
1486//
1487// Arguments:
093abf11
KM
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.
f8942e07
SH
1492// Returns:
1493// OSAL_STATUS_CODE
1494//
1495//-----------------------------------------------------------------------------
1496
093abf11
KM
1497static INT BeceemEEPROMReadBackandVerify(struct bcm_mini_adapter *Adapter,
1498 PUINT pBuffer,
1499 UINT uiOffset,
1500 UINT uiNumBytes)
f8942e07 1501{
093abf11
KM
1502 UINT uiRdbk = 0;
1503 UINT uiIndex = 0;
1504 UINT uiData = 0;
1505 UINT auiData[4] = {0};
f8942e07 1506
a2940b63 1507 while (uiNumBytes) {
093abf11 1508 if (Adapter->device_removed)
f8942e07 1509 return -1;
f8942e07 1510
a2940b63
KM
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.
093abf11 1513 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
f8942e07 1514
a2940b63 1515 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE)) {
f8942e07 1516 // re-write
093abf11 1517 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, MAX_RW_SIZE, FALSE);
f8942e07 1518 mdelay(3);
093abf11 1519 BeceemEEPROMBulkRead(Adapter, &auiData[0], uiOffset, MAX_RW_SIZE);
f8942e07 1520
093abf11 1521 if (memcmp(&pBuffer[uiIndex], &auiData[0], MAX_RW_SIZE))
f8942e07 1522 return -1;
f8942e07
SH
1523 }
1524 uiOffset += MAX_RW_SIZE;
1525 uiNumBytes -= MAX_RW_SIZE;
1526 uiIndex += 4;
a2940b63 1527 } else if (uiNumBytes >= 4) {
093abf11 1528 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
a2940b63 1529 if (uiData != pBuffer[uiIndex]) {
093abf11
KM
1530 // re-write
1531 BeceemEEPROMBulkWrite(Adapter, (PUCHAR)(pBuffer + uiIndex), uiOffset, 4, FALSE);
f8942e07 1532 mdelay(3);
093abf11
KM
1533 BeceemEEPROMBulkRead(Adapter, &uiData, uiOffset, 4);
1534 if (uiData != pBuffer[uiIndex])
f8942e07 1535 return -1;
f8942e07
SH
1536 }
1537 uiOffset += 4;
1538 uiNumBytes -= 4;
1539 uiIndex++;
a2940b63
KM
1540 } else {
1541 // Handle the reads less than 4 bytes...
f8942e07 1542 uiData = 0;
093abf11
KM
1543 memcpy(&uiData, ((PUCHAR)pBuffer) + (uiIndex * sizeof(UINT)), uiNumBytes);
1544 BeceemEEPROMBulkRead(Adapter, &uiRdbk, uiOffset, 4);
f8942e07 1545
093abf11 1546 if (memcmp(&uiData, &uiRdbk, uiNumBytes))
f8942e07
SH
1547 return -1;
1548
1549 uiNumBytes = 0;
1550 }
f8942e07
SH
1551 }
1552
1553 return 0;
1554}
1555
a2940b63
KM
1556static VOID BcmSwapWord(UINT *ptr1)
1557{
093abf11 1558 UINT tempval = (UINT)*ptr1;
f8942e07
SH
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:
093abf11
KM
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.
f8942e07
SH
1577// Returns:
1578// OSAL_STATUS_CODE
1579//
1580//-----------------------------------------------------------------------------
093abf11
KM
1581
1582static INT BeceemEEPROMWritePage(struct bcm_mini_adapter *Adapter, UINT uiData[], UINT uiOffset)
f8942e07 1583{
093abf11 1584 UINT uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
f8942e07
SH
1585 UINT uiStatus = 0;
1586 UCHAR uiEpromStatus = 0;
093abf11 1587 UINT value = 0;
f8942e07
SH
1588
1589 /* Flush the Write/Read/Cmd queues. */
093abf11
KM
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));
f8942e07
SH
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. */
093abf11
KM
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));
f8942e07
SH
1601
1602 /* Enable write */
093abf11
KM
1603 value = EEPROM_WRITE_ENABLE;
1604 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
f8942e07
SH
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);
093abf11 1611 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
f8942e07
SH
1612
1613 value = uiData[1];
1614 BcmSwapWord(&value);
093abf11 1615 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
f8942e07
SH
1616
1617 value = uiData[2];
1618 BcmSwapWord(&value);
093abf11 1619 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
f8942e07
SH
1620
1621 value = uiData[3];
1622 BcmSwapWord(&value);
093abf11 1623 wrm(Adapter, EEPROM_WRITE_DATAQ_REG, (PUCHAR)&value, 4);
f8942e07
SH
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. */
093abf11
KM
1629 value = EEPROM_16_BYTE_PAGE_WRITE | uiOffset;
1630 wrmalt(Adapter, EEPROM_CMDQ_SPI_REG, &value, sizeof(value));
f8942e07
SH
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;
41c7b7c0 1636 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
a2940b63 1637 while ((uiStatus & EEPROM_WRITE_QUEUE_EMPTY) == 0) {
f8942e07 1638 uiRetries--;
a2940b63 1639 if (uiRetries == 0) {
093abf11
KM
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;
f8942e07
SH
1642 }
1643
093abf11
KM
1644 if (!(uiRetries%RETRIES_PER_DELAY))
1645 msleep(1);
f8942e07
SH
1646
1647 uiStatus = 0;
41c7b7c0 1648 rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &uiStatus, sizeof(uiStatus));
a2940b63 1649 if (Adapter->device_removed == TRUE) {
093abf11 1650 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem got removed hence exiting from loop....");
f8942e07
SH
1651 return -ENODEV;
1652 }
f8942e07
SH
1653 }
1654
a2940b63 1655 if (uiRetries != 0) {
f8942e07 1656 /* Clear the ones that are set - either, Empty/Full/Avail bits */
093abf11
KM
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));
f8942e07
SH
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. */
093abf11 1666 uiRetries = MAX_EEPROM_RETRIES * RETRIES_PER_DELAY;
f8942e07 1667 uiEpromStatus = 0;
a2940b63 1668 while (uiRetries != 0) {
093abf11 1669 uiEpromStatus = ReadEEPROMStatusRegister(Adapter);
a2940b63 1670 if (Adapter->device_removed == TRUE) {
093abf11 1671 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Modem has got removed hence exiting from loop...");
f8942e07
SH
1672 return -ENODEV;
1673 }
a2940b63 1674 if ((EEPROM_STATUS_REG_WRITE_BUSY & uiEpromStatus) == 0) {
093abf11
KM
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;
f8942e07
SH
1677 }
1678 uiRetries--;
a2940b63 1679 if (uiRetries == 0) {
093abf11
KM
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;
f8942e07
SH
1682 }
1683 uiEpromStatus = 0;
093abf11
KM
1684 if (!(uiRetries%RETRIES_PER_DELAY))
1685 msleep(1);
f8942e07
SH
1686 }
1687
093abf11 1688 return STATUS_SUCCESS;
f8942e07
SH
1689} /* BeceemEEPROMWritePage */
1690
f8942e07
SH
1691//-----------------------------------------------------------------------------
1692// Procedure: BeceemEEPROMBulkWrite
1693//
1694// Description: Performs write to the EEPROM
1695//
1696// Arguments:
093abf11
KM
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.
f8942e07
SH
1702// Returns:
1703// OSAL_STATUS_CODE
1704//
1705//-----------------------------------------------------------------------------
1706
093abf11
KM
1707INT BeceemEEPROMBulkWrite(struct bcm_mini_adapter *Adapter,
1708 PUCHAR pBuffer,
1709 UINT uiOffset,
1710 UINT uiNumBytes,
1711 BOOLEAN bVerify)
f8942e07 1712{
093abf11
KM
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;
f8942e07 1721
a2940b63 1722 if (uiOffset % MAX_RW_SIZE && uiBytesToCopy) {
093abf11
KM
1723 uiTempOffset = uiOffset - (uiOffset % MAX_RW_SIZE);
1724 uiExtraBytes = uiOffset - uiTempOffset;
f8942e07 1725
093abf11 1726 BeceemEEPROMBulkRead(Adapter, &uiData[0], uiTempOffset, MAX_RW_SIZE);
f8942e07 1727
a2940b63 1728 if (uiBytesToCopy >= (16 - uiExtraBytes)) {
093abf11 1729 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, MAX_RW_SIZE - uiExtraBytes);
f8942e07 1730
093abf11
KM
1731 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
1732 return STATUS_FAILURE;
f8942e07
SH
1733
1734 uiBytesToCopy -= (MAX_RW_SIZE - uiExtraBytes);
1735 uiIndex += (MAX_RW_SIZE - uiExtraBytes);
1736 uiOffset += (MAX_RW_SIZE - uiExtraBytes);
a2940b63 1737 } else {
093abf11 1738 memcpy((((PUCHAR)&uiData[0]) + uiExtraBytes), pBuffer, uiBytesToCopy);
f8942e07 1739
093abf11
KM
1740 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiTempOffset))
1741 return STATUS_FAILURE;
f8942e07
SH
1742
1743 uiIndex += uiBytesToCopy;
1744 uiOffset += uiBytesToCopy;
1745 uiBytesToCopy = 0;
1746 }
f8942e07
SH
1747 }
1748
a2940b63 1749 while (uiBytesToCopy) {
093abf11 1750 if (Adapter->device_removed)
f8942e07 1751 return -1;
f8942e07 1752
a2940b63 1753 if (uiBytesToCopy >= MAX_RW_SIZE) {
093abf11
KM
1754 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, (PUINT) &pBuffer[uiIndex], uiOffset))
1755 return STATUS_FAILURE;
f8942e07
SH
1756
1757 uiIndex += MAX_RW_SIZE;
1758 uiOffset += MAX_RW_SIZE;
093abf11 1759 uiBytesToCopy -= MAX_RW_SIZE;
a2940b63 1760 } else {
093abf11
KM
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);
f8942e07 1766
093abf11
KM
1767 if (STATUS_FAILURE == BeceemEEPROMWritePage(Adapter, uiData, uiOffset))
1768 return STATUS_FAILURE;
f8942e07 1769
f8942e07
SH
1770 uiBytesToCopy = 0;
1771 }
f8942e07
SH
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:
25985edc 1789// OSAL_STATUS_SUCCESS - if NVM read is successful.
f8942e07
SH
1790// <FAILURE> - if failed.
1791//-----------------------------------------------------------------------------
1792
093abf11
KM
1793INT BeceemNVMRead(struct bcm_mini_adapter *Adapter,
1794 PUINT pBuffer,
1795 UINT uiOffset,
1796 UINT uiNumBytes)
f8942e07
SH
1797{
1798 INT Status = 0;
f8942e07 1799
093abf11
KM
1800 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
1801 UINT uiTemp = 0, value;
1802 #endif
1803
a2940b63
KM
1804 if (Adapter->eNVMType == NVM_FLASH) {
1805 if (Adapter->bFlashRawRead == FALSE) {
093abf11
KM
1806 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
1807 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes);
1808
1809 uiOffset = uiOffset + Adapter->ulFlashCalStart;
f8942e07 1810 }
f8942e07 1811
093abf11
KM
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,
f8942e07
SH
1819 pBuffer,
1820 uiOffset,
1821 uiNumBytes);
093abf11
KM
1822 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1823 #endif
a2940b63 1824 } else if (Adapter->eNVMType == NVM_EEPROM) {
f8942e07
SH
1825 Status = BeceemEEPROMBulkRead(Adapter,
1826 pBuffer,
1827 uiOffset,
1828 uiNumBytes);
a2940b63 1829 } else {
f8942e07
SH
1830 Status = -1;
1831 }
093abf11 1832
f8942e07
SH
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:
25985edc 1848// OSAL_STATUS_SUCCESS - if NVM write is successful.
f8942e07
SH
1849// <FAILURE> - if failed.
1850//-----------------------------------------------------------------------------
1851
093abf11
KM
1852INT BeceemNVMWrite(struct bcm_mini_adapter *Adapter,
1853 PUINT pBuffer,
1854 UINT uiOffset,
1855 UINT uiNumBytes,
1856 BOOLEAN bVerify)
f8942e07
SH
1857{
1858 INT Status = 0;
1859 UINT uiTemp = 0;
1860 UINT uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC;
1861 UINT uiIndex = 0;
093abf11
KM
1862
1863 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
1864 UINT value;
1865 #endif
1866
f8942e07
SH
1867 UINT uiFlashOffset = 0;
1868
a2940b63 1869 if (Adapter->eNVMType == NVM_FLASH) {
093abf11
KM
1870 if (IsSectionExistInVendorInfo(Adapter, Adapter->eActiveDSD))
1871 Status = vendorextnWriteSection(Adapter, (PUCHAR)pBuffer, Adapter->eActiveDSD, uiOffset, uiNumBytes, bVerify);
a2940b63 1872 else {
f8942e07
SH
1873 uiFlashOffset = uiOffset + Adapter->ulFlashCalStart;
1874
093abf11
KM
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));
f8942e07 1881
093abf11 1882 if (Adapter->bStatusWrite == TRUE)
093abf11
KM
1883 Status = BeceemFlashBulkWriteStatus(Adapter,
1884 pBuffer,
1885 uiFlashOffset,
1886 uiNumBytes ,
1887 bVerify);
093abf11 1888 else
f8942e07 1889
093abf11
KM
1890 Status = BeceemFlashBulkWrite(Adapter,
1891 pBuffer,
1892 uiFlashOffset,
1893 uiNumBytes,
1894 bVerify);
093abf11 1895 #endif
f8942e07
SH
1896 }
1897
a2940b63 1898 if (uiOffset >= EEPROM_CALPARAM_START) {
f8942e07 1899 uiMemoryLoc += (uiOffset - EEPROM_CALPARAM_START);
a2940b63
KM
1900 while (uiNumBytes) {
1901 if (uiNumBytes > BUFFER_4K) {
093abf11 1902 wrm(Adapter, (uiMemoryLoc+uiIndex), (PCHAR)(pBuffer + (uiIndex / 4)), BUFFER_4K);
f8942e07
SH
1903 uiNumBytes -= BUFFER_4K;
1904 uiIndex += BUFFER_4K;
a2940b63 1905 } else {
093abf11 1906 wrm(Adapter, uiMemoryLoc+uiIndex, (PCHAR)(pBuffer + (uiIndex / 4)), uiNumBytes);
f8942e07
SH
1907 uiNumBytes = 0;
1908 break;
1909 }
1910 }
a2940b63
KM
1911 } else {
1912 if ((uiOffset + uiNumBytes) > EEPROM_CALPARAM_START) {
f8942e07 1913 ULONG ulBytesTobeSkipped = 0;
093abf11 1914 PUCHAR pcBuffer = (PUCHAR)pBuffer; // char pointer to take care of odd byte cases.
f8942e07
SH
1915 uiNumBytes -= (EEPROM_CALPARAM_START - uiOffset);
1916 ulBytesTobeSkipped += (EEPROM_CALPARAM_START - uiOffset);
1917 uiOffset += (EEPROM_CALPARAM_START - uiOffset);
a2940b63
KM
1918 while (uiNumBytes) {
1919 if (uiNumBytes > BUFFER_4K) {
093abf11 1920 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], BUFFER_4K);
f8942e07
SH
1921 uiNumBytes -= BUFFER_4K;
1922 uiIndex += BUFFER_4K;
a2940b63 1923 } else {
093abf11 1924 wrm(Adapter, uiMemoryLoc + uiIndex, (PCHAR)&pcBuffer[ulBytesTobeSkipped + uiIndex], uiNumBytes);
f8942e07
SH
1925 uiNumBytes = 0;
1926 break;
1927 }
1928 }
f8942e07
SH
1929 }
1930 }
093abf11
KM
1931 // restore the values.
1932 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
a2940b63 1933 } else if (Adapter->eNVMType == NVM_EEPROM) {
f8942e07
SH
1934 Status = BeceemEEPROMBulkWrite(Adapter,
1935 (PUCHAR)pBuffer,
1936 uiOffset,
1937 uiNumBytes,
1938 bVerify);
093abf11 1939 if (bVerify)
093abf11 1940 Status = BeceemEEPROMReadBackandVerify(Adapter, (PUINT)pBuffer, uiOffset, uiNumBytes);
a2940b63 1941 } else {
f8942e07
SH
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:
25985edc 1957// OSAL_STATUS_SUCCESS - if NVM write is successful.
f8942e07
SH
1958// <FAILURE> - if failed.
1959//-----------------------------------------------------------------------------
1960
093abf11 1961INT BcmUpdateSectorSize(struct bcm_mini_adapter *Adapter, UINT uiSectorSize)
f8942e07
SH
1962{
1963 INT Status = -1;
1964 FLASH_CS_INFO sFlashCsInfo = {0};
1965 UINT uiTemp = 0;
f8942e07
SH
1966 UINT uiSectorSig = 0;
1967 UINT uiCurrentSectorSize = 0;
f8942e07
SH
1968 UINT value;
1969
f8942e07
SH
1970 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
1971 value = 0;
093abf11 1972 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
f8942e07 1973
093abf11
KM
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));
f8942e07
SH
1978 uiSectorSig = ntohl(sFlashCsInfo.FlashSectorSizeSig);
1979 uiCurrentSectorSize = ntohl(sFlashCsInfo.FlashSectorSize);
1980
a2940b63
KM
1981 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
1982 if ((uiCurrentSectorSize <= MAX_SECTOR_SIZE) && (uiCurrentSectorSize >= MIN_SECTOR_SIZE)) {
1983 if (uiSectorSize == uiCurrentSectorSize) {
093abf11 1984 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Provided sector size is same as programmed in Flash");
f8942e07 1985 Status = STATUS_SUCCESS;
093abf11 1986 goto Restore;
f8942e07
SH
1987 }
1988 }
1989 }
1990
a2940b63 1991 if ((uiSectorSize <= MAX_SECTOR_SIZE) && (uiSectorSize >= MIN_SECTOR_SIZE)) {
f8942e07
SH
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);
f8942e07
SH
2000 }
2001
093abf11 2002Restore:
f8942e07 2003 // restore the values.
093abf11 2004 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
f8942e07
SH
2005
2006 return Status;
f8942e07
SH
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
2979460d 2022static UINT BcmGetFlashSectorSize(struct bcm_mini_adapter *Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize)
f8942e07
SH
2023{
2024 UINT uiSectorSize = 0;
2025 UINT uiSectorSig = 0;
2026
093abf11 2027 if (Adapter->bSectorSizeOverride &&
f8942e07 2028 (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
a2940b63 2029 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)) {
f8942e07 2030 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
a2940b63 2031 } else {
f8942e07
SH
2032 uiSectorSig = FlashSectorSizeSig;
2033
a2940b63 2034 if (uiSectorSig == FLASH_SECTOR_SIZE_SIG) {
f8942e07 2035 uiSectorSize = FlashSectorSize;
093abf11
KM
2036 //
2037 // If the sector size stored in the FLASH makes sense then use it.
2038 //
a2940b63 2039 if (uiSectorSize <= MAX_SECTOR_SIZE && uiSectorSize >= MIN_SECTOR_SIZE) {
f8942e07 2040 Adapter->uiSectorSize = uiSectorSize;
a2940b63
KM
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.
f8942e07 2044 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
a2940b63
KM
2045 } else {
2046 // Init to Default, if none of the above works.
f8942e07
SH
2047 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
2048 }
a2940b63 2049 } else {
093abf11
KM
2050 if (Adapter->uiSectorSizeInCFG <= MAX_SECTOR_SIZE &&
2051 Adapter->uiSectorSizeInCFG >= MIN_SECTOR_SIZE)
f8942e07 2052 Adapter->uiSectorSize = Adapter->uiSectorSizeInCFG;
f8942e07 2053 else
f8942e07 2054 Adapter->uiSectorSize = DEFAULT_SECTOR_SIZE;
f8942e07
SH
2055 }
2056 }
2057
093abf11
KM
2058 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Sector size :%x\n", Adapter->uiSectorSize);
2059
f8942e07
SH
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
2979460d 2075static INT BcmInitEEPROMQueues(struct bcm_mini_adapter *Adapter)
f8942e07
SH
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. */
093abf11 2081 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Fixing reset value on 0x0f003004 register\n");
f8942e07 2082 value = EEPROM_READ_DATA_AVAIL;
093abf11 2083 wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value));
f8942e07
SH
2084
2085 /* Flush the all the EEPROM queues. */
093abf11
KM
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));
f8942e07
SH
2089
2090 value = 0;
093abf11 2091 wrmalt(Adapter, SPI_FLUSH_REG, &value, sizeof(value));
f8942e07
SH
2092
2093 /* Read the EEPROM Status Register. Just to see, no real purpose. */
093abf11 2094 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "EEPROM Status register value = %x\n", ReadEEPROMStatusRegister(Adapter));
f8942e07
SH
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
2979460d 2111INT BcmInitNVM(struct bcm_mini_adapter *ps_adapter)
f8942e07 2112{
f8942e07
SH
2113 BcmValidateNvmType(ps_adapter);
2114 BcmInitEEPROMQueues(ps_adapter);
f8942e07 2115
a2940b63 2116 if (ps_adapter->eNVMType == NVM_AUTODETECT) {
f8942e07 2117 ps_adapter->eNVMType = BcmGetNvmType(ps_adapter);
093abf11 2118 if (ps_adapter->eNVMType == NVM_UNKNOWN)
093abf11 2119 BCM_DEBUG_PRINT(ps_adapter, DBG_TYPE_PRINTK, 0, 0, "NVM Type is unknown!!\n");
a2940b63 2120 } else if (ps_adapter->eNVMType == NVM_FLASH) {
f8942e07
SH
2121 BcmGetFlashCSInfo(ps_adapter);
2122 }
2123
2124 BcmGetNvmSize(ps_adapter);
2125
2126 return STATUS_SUCCESS;
2127}
093abf11 2128
f8942e07
SH
2129/***************************************************************************/
2130/*BcmGetNvmSize : set the EEPROM or flash size in Adapter.
2131*
2132*Input Parameter:
2133* Adapter data structure
2134*Return Value :
25985edc 2135* 0. means success;
f8942e07
SH
2136*/
2137/***************************************************************************/
2138
2979460d 2139static INT BcmGetNvmSize(struct bcm_mini_adapter *Adapter)
f8942e07 2140{
093abf11 2141 if (Adapter->eNVMType == NVM_EEPROM)
f8942e07 2142 Adapter->uiNVMDSDSize = BcmGetEEPROMSize(Adapter);
093abf11 2143 else if (Adapter->eNVMType == NVM_FLASH)
f8942e07 2144 Adapter->uiNVMDSDSize = BcmGetFlashSize(Adapter);
a2940b63 2145
f8942e07
SH
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//-----------------------------------------------------------------------------
093abf11 2160
2979460d 2161static VOID BcmValidateNvmType(struct bcm_mini_adapter *Adapter)
f8942e07 2162{
f8942e07
SH
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
093abf11 2169 if (Adapter->eNVMType == NVM_FLASH &&
f8942e07 2170 Adapter->chip_id < 0xBECE3300)
f8942e07 2171 Adapter->eNVMType = NVM_AUTODETECT;
f8942e07 2172}
093abf11 2173
f8942e07
SH
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//-----------------------------------------------------------------------------
093abf11 2185
2979460d 2186static ULONG BcmReadFlashRDID(struct bcm_mini_adapter *Adapter)
f8942e07
SH
2187{
2188 ULONG ulRDID = 0;
2189 UINT value;
f8942e07 2190
093abf11
KM
2191 //
2192 // Read ID Instruction.
2193 //
2194 value = (FLASH_CMD_READ_ID << 24);
2195 wrmalt(Adapter, FLASH_SPI_CMDQ_REG, &value, sizeof(value));
f8942e07 2196
093abf11
KM
2197 //Delay
2198 udelay(10);
f8942e07 2199
093abf11
KM
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));
f8942e07 2205
093abf11 2206 return (ulRDID >> 8);
f8942e07
SH
2207}
2208
2979460d 2209INT BcmAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
f8942e07 2210{
a2940b63 2211 if (psAdapter == NULL) {
093abf11 2212 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
f8942e07
SH
2213 return -EINVAL;
2214 }
2215 psAdapter->psFlashCSInfo = (PFLASH_CS_INFO)kzalloc(sizeof(FLASH_CS_INFO), GFP_KERNEL);
a2940b63 2216 if (psAdapter->psFlashCSInfo == NULL) {
093abf11 2217 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 1.x");
f8942e07
SH
2218 return -ENOMEM;
2219 }
2220
2221 psAdapter->psFlash2xCSInfo = (PFLASH2X_CS_INFO)kzalloc(sizeof(FLASH2X_CS_INFO), GFP_KERNEL);
a2940b63 2222 if (psAdapter->psFlash2xCSInfo == NULL) {
093abf11 2223 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate memory for Flash 2.x");
082e889b 2224 kfree(psAdapter->psFlashCSInfo);
f8942e07
SH
2225 return -ENOMEM;
2226 }
2227
2228 psAdapter->psFlash2xVendorInfo = (PFLASH2X_VENDORSPECIFIC_INFO)kzalloc(sizeof(FLASH2X_VENDORSPECIFIC_INFO), GFP_KERNEL);
a2940b63 2229 if (psAdapter->psFlash2xVendorInfo == NULL) {
093abf11 2230 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Can't Allocate Vendor Info Memory for Flash 2.x");
082e889b
SH
2231 kfree(psAdapter->psFlashCSInfo);
2232 kfree(psAdapter->psFlash2xCSInfo);
f8942e07
SH
2233 return -ENOMEM;
2234 }
2235
2236 return STATUS_SUCCESS;
2237}
2238
2979460d 2239INT BcmDeAllocFlashCSStructure(struct bcm_mini_adapter *psAdapter)
f8942e07 2240{
a2940b63 2241 if (psAdapter == NULL) {
093abf11 2242 BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure point is NULL");
f8942e07
SH
2243 return -EINVAL;
2244 }
082e889b
SH
2245 kfree(psAdapter->psFlashCSInfo);
2246 kfree(psAdapter->psFlash2xCSInfo);
2247 kfree(psAdapter->psFlash2xVendorInfo);
093abf11 2248 return STATUS_SUCCESS;
f8942e07
SH
2249}
2250
093abf11 2251static INT BcmDumpFlash2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo, struct bcm_mini_adapter *Adapter)
f8942e07
SH
2252{
2253 UINT Index = 0;
093abf11
KM
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++)
093abf11 2305 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "SectorAccessBitMap[%d] :0x%x", Index,
f8942e07 2306 (psFlash2xCSInfo->SectorAccessBitMap[Index]));
f8942e07
SH
2307
2308 return STATUS_SUCCESS;
2309}
2310
093abf11 2311static INT ConvertEndianOf2XCSStructure(PFLASH2X_CS_INFO psFlash2xCSInfo)
f8942e07
SH
2312{
2313 UINT Index = 0;
093abf11 2314
f8942e07 2315 psFlash2xCSInfo->MagicNumber = ntohl(psFlash2xCSInfo->MagicNumber);
093abf11 2316 psFlash2xCSInfo->FlashLayoutVersion = ntohl(psFlash2xCSInfo->FlashLayoutVersion);
f8942e07
SH
2317 //psFlash2xCSInfo->FlashLayoutMinorVersion = ntohs(psFlash2xCSInfo->FlashLayoutMinorVersion);
2318 psFlash2xCSInfo->ISOImageVersion = ntohl(psFlash2xCSInfo->ISOImageVersion);
093abf11 2319 psFlash2xCSInfo->SCSIFirmwareVersion = ntohl(psFlash2xCSInfo->SCSIFirmwareVersion);
f8942e07
SH
2320 psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage = ntohl(psFlash2xCSInfo->OffsetFromZeroForPart1ISOImage);
2321 psFlash2xCSInfo->OffsetFromZeroForScsiFirmware = ntohl(psFlash2xCSInfo->OffsetFromZeroForScsiFirmware);
093abf11 2322 psFlash2xCSInfo->SizeOfScsiFirmware = ntohl(psFlash2xCSInfo->SizeOfScsiFirmware);
f8942e07
SH
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);
093abf11
KM
2361
2362 for (Index = 0; Index < (FLASH2X_TOTAL_SIZE / (DEFAULT_SECTOR_SIZE * 16)); Index++)
093abf11 2363 psFlash2xCSInfo->SectorAccessBitMap[Index] = ntohl(psFlash2xCSInfo->SectorAccessBitMap[Index]);
a2940b63 2364
f8942e07
SH
2365 return STATUS_SUCCESS;
2366}
2367
093abf11 2368static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo)
f8942e07
SH
2369{
2370 //UINT Index = 0;
093abf11
KM
2371 psFlashCSInfo->MagicNumber = ntohl(psFlashCSInfo->MagicNumber);
2372 psFlashCSInfo->FlashLayoutVersion = ntohl(psFlashCSInfo->FlashLayoutVersion);
2373 psFlashCSInfo->ISOImageVersion = ntohl(psFlashCSInfo->ISOImageVersion);
f8942e07 2374 //won't convert according to old assumption
093abf11
KM
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);
f8942e07
SH
2396
2397 return STATUS_SUCCESS;
2398}
2399
2979460d 2400static INT IsSectionExistInVendorInfo(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section)
f8942e07 2401{
093abf11
KM
2402 return (Adapter->uiVendorExtnFlag &&
2403 (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) &&
2404 (Adapter->psFlash2xVendorInfo->VendorSection[section].OffsetFromZeroForSectionStart != UNINIT_PTR_IN_CS));
f8942e07
SH
2405}
2406
2979460d 2407static VOID UpdateVendorInfo(struct bcm_mini_adapter *Adapter)
f8942e07
SH
2408{
2409 B_UINT32 i = 0;
2410 UINT uiSizeSection = 0;
2411
2412 Adapter->uiVendorExtnFlag = FALSE;
2413
093abf11 2414 for (i = 0; i < TOTAL_SECTIONS; i++)
f8942e07
SH
2415 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart = UNINIT_PTR_IN_CS;
2416
093abf11 2417 if (STATUS_SUCCESS != vendorextnGetSectionInfo(Adapter, Adapter->psFlash2xVendorInfo))
f8942e07
SH
2418 return;
2419
2420 i = 0;
a2940b63
KM
2421 while (i < TOTAL_SECTIONS) {
2422 if (!(Adapter->psFlash2xVendorInfo->VendorSection[i].AccessFlags & FLASH2X_SECTION_PRESENT)) {
f8942e07
SH
2423 i++;
2424 continue;
2425 }
2426
2427 Adapter->uiVendorExtnFlag = TRUE;
2428 uiSizeSection = (Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionEnd -
093abf11 2429 Adapter->psFlash2xVendorInfo->VendorSection[i].OffsetFromZeroForSectionStart);
f8942e07 2430
a2940b63
KM
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;
f8942e07 2439
a2940b63
KM
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;
f8942e07 2447
a2940b63
KM
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;
f8942e07 2461
a2940b63
KM
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;
f8942e07 2474
a2940b63
KM
2475 default:
2476 break;
f8942e07
SH
2477 }
2478 i++;
2479 }
f8942e07
SH
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
2979460d 2494static INT BcmGetFlashCSInfo(struct bcm_mini_adapter *Adapter)
f8942e07
SH
2495{
2496 //FLASH_CS_INFO sFlashCsInfo = {0};
2497
093abf11
KM
2498 #if !defined(BCM_SHM_INTERFACE) || defined(FLASH_DIRECT_ACCESS)
2499 UINT value;
2500 #endif
2501
f8942e07
SH
2502 UINT uiFlashLayoutMajorVersion;
2503 Adapter->uiFlashLayoutMinorVersion = 0;
2504 Adapter->uiFlashLayoutMajorVersion = 0;
2505 Adapter->ulFlashControlSectionStart = FLASH_CS_INFO_START_ADDR;
2506
f8942e07
SH
2507 Adapter->uiFlashBaseAdd = 0;
2508 Adapter->ulFlashCalStart = 0;
093abf11
KM
2509 memset(Adapter->psFlashCSInfo, 0 , sizeof(FLASH_CS_INFO));
2510 memset(Adapter->psFlash2xCSInfo, 0 , sizeof(FLASH2X_CS_INFO));
f8942e07 2511
a2940b63
KM
2512 if (!Adapter->bDDRInitDone) {
2513 value = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
2514 wrmalt(Adapter, 0xAF00A080, &value, sizeof(value));
f8942e07
SH
2515 }
2516
f8942e07
SH
2517 // Reading first 8 Bytes to get the Flash Layout
2518 // MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes)
093abf11 2519 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, 8);
f8942e07
SH
2520
2521 Adapter->psFlashCSInfo->FlashLayoutVersion = ntohl(Adapter->psFlashCSInfo->FlashLayoutVersion);
093abf11 2522 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Version :%X", (Adapter->psFlashCSInfo->FlashLayoutVersion));
f8942e07 2523 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Flash Layout Minor Version :%d\n", ntohs(sFlashCsInfo.FlashLayoutMinorVersion));
093abf11 2524 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is :%x\n", ntohl(Adapter->psFlashCSInfo->MagicNumber));
f8942e07 2525
a2940b63 2526 if (FLASH_CONTROL_STRUCT_SIGNATURE == ntohl(Adapter->psFlashCSInfo->MagicNumber)) {
f8942e07
SH
2527 uiFlashLayoutMajorVersion = MAJOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
2528 Adapter->uiFlashLayoutMinorVersion = MINOR_VERSION((Adapter->psFlashCSInfo->FlashLayoutVersion));
a2940b63 2529 } else {
f8942e07
SH
2530 Adapter->uiFlashLayoutMinorVersion = 0;
2531 uiFlashLayoutMajorVersion = 0;
2532 }
2533
093abf11 2534 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "FLASH LAYOUT MAJOR VERSION :%X", uiFlashLayoutMajorVersion);
f8942e07 2535
a2940b63 2536 if (uiFlashLayoutMajorVersion < FLASH_2X_MAJOR_NUMBER) {
093abf11 2537 BeceemFlashBulkRead(Adapter, (PUINT)Adapter->psFlashCSInfo, Adapter->ulFlashControlSectionStart, sizeof(FLASH_CS_INFO));
f8942e07
SH
2538 ConvertEndianOfCSStructure(Adapter->psFlashCSInfo);
2539 Adapter->ulFlashCalStart = (Adapter->psFlashCSInfo->OffsetFromZeroForCalibrationStart);
2540
093abf11 2541 if (!((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
f8942e07 2542 Adapter->ulFlashControlSectionStart = Adapter->psFlashCSInfo->OffsetFromZeroForControlSectionStart;
f8942e07 2543
093abf11
KM
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)) &&
a2940b63 2547 (BYTE_WRITE_SUPPORT == (Adapter->psFlashCSInfo->FlashWriteSupportSize))) {
f8942e07 2548 Adapter->ulFlashWriteSize = (Adapter->psFlashCSInfo->FlashWriteSupportSize);
093abf11
KM
2549 Adapter->fpFlashWrite = flashByteWrite;
2550 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
a2940b63 2551 } else {
f8942e07
SH
2552 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2553 Adapter->fpFlashWrite = flashWrite;
093abf11 2554 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
f8942e07
SH
2555 }
2556
2557 BcmGetFlashSectorSize(Adapter, (Adapter->psFlashCSInfo->FlashSectorSizeSig),
093abf11 2558 (Adapter->psFlashCSInfo->FlashSectorSize));
f8942e07 2559 Adapter->uiFlashBaseAdd = Adapter->psFlashCSInfo->FlashBaseAddr & 0xFCFFFFFF;
a2940b63 2560 } else {
093abf11 2561 if (BcmFlash2xBulkRead(Adapter, (PUINT)Adapter->psFlash2xCSInfo, NO_SECTION_VAL,
a2940b63 2562 Adapter->ulFlashControlSectionStart, sizeof(FLASH2X_CS_INFO))) {
093abf11 2563 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to read CS structure\n");
f8942e07
SH
2564 return STATUS_FAILURE;
2565 }
093abf11 2566
f8942e07 2567 ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo);
093abf11
KM
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) &&
a2940b63 2572 (BYTE_WRITE_SUPPORT == Adapter->psFlash2xCSInfo->FlashWriteSupportSize)) {
f8942e07 2573 Adapter->ulFlashWriteSize = Adapter->psFlash2xCSInfo->FlashWriteSupportSize;
093abf11
KM
2574 Adapter->fpFlashWrite = flashByteWrite;
2575 Adapter->fpFlashWriteWithStatusCheck = flashByteWriteStatus;
a2940b63 2576 } else {
f8942e07
SH
2577 Adapter->ulFlashWriteSize = MAX_RW_SIZE;
2578 Adapter->fpFlashWrite = flashWrite;
093abf11 2579 Adapter->fpFlashWriteWithStatusCheck = flashWriteStatus;
f8942e07
SH
2580 }
2581
2582 BcmGetFlashSectorSize(Adapter, Adapter->psFlash2xCSInfo->FlashSectorSizeSig,
093abf11 2583 Adapter->psFlash2xCSInfo->FlashSectorSize);
f8942e07
SH
2584
2585 UpdateVendorInfo(Adapter);
2586
2587 BcmGetActiveDSD(Adapter);
2588 BcmGetActiveISO(Adapter);
2589 Adapter->uiFlashBaseAdd = Adapter->psFlash2xCSInfo->FlashBaseAddr & 0xFCFFFFFF;
2590 Adapter->ulFlashControlSectionStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForControlSectionStart;
f8942e07
SH
2591 }
2592 /*
093abf11
KM
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 ????
f8942e07 2595 */
f8942e07 2596 Adapter->ulFlashID = BcmReadFlashRDID(Adapter);
f8942e07
SH
2597 Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion;
2598
093abf11 2599 return STATUS_SUCCESS;
f8942e07
SH
2600}
2601
f8942e07
SH
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
2979460d 2615static NVM_TYPE BcmGetNvmType(struct bcm_mini_adapter *Adapter)
f8942e07
SH
2616{
2617 UINT uiData = 0;
2618
093abf11
KM
2619 BeceemEEPROMBulkRead(Adapter, &uiData, 0x0, 4);
2620 if (uiData == BECM)
f8942e07 2621 return NVM_EEPROM;
093abf11 2622
f8942e07
SH
2623 //
2624 // Read control struct and get cal addresses before accessing the flash
2625 //
2626 BcmGetFlashCSInfo(Adapter);
2627
093abf11
KM
2628 BeceemFlashBulkRead(Adapter, &uiData, 0x0 + Adapter->ulFlashCalStart, 4);
2629 if (uiData == BECM)
f8942e07 2630 return NVM_FLASH;
093abf11
KM
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))
f8942e07 2637 return NVM_EEPROM;
f8942e07 2638
093abf11 2639 //TBD for Flash.
f8942e07
SH
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
2979460d 2653INT BcmGetSectionValStartOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
f8942e07
SH
2654{
2655 /*
093abf11
KM
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 */
f8942e07 2660
093abf11 2661 INT SectStartOffset = 0;
f8942e07 2662
093abf11 2663 SectStartOffset = INVALID_OFFSET;
f8942e07 2664
093abf11 2665 if (IsSectionExistInVendorInfo(Adapter, eFlashSectionVal))
f8942e07 2666 return Adapter->psFlash2xVendorInfo->VendorSection[eFlashSectionVal].OffsetFromZeroForSectionStart;
f8942e07 2667
a2940b63
KM
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;
f8942e07 2730 }
093abf11 2731
f8942e07
SH
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
2979460d 2745INT BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
f8942e07 2746{
093abf11 2747 INT SectEndOffset = 0;
f8942e07 2748
093abf11
KM
2749 SectEndOffset = INVALID_OFFSET;
2750 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
f8942e07 2751 return Adapter->psFlash2xVendorInfo->VendorSection[eFlash2xSectionVal].OffsetFromZeroForSectionEnd;
f8942e07 2752
a2940b63
KM
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;
f8942e07 2814 }
093abf11 2815
f8942e07
SH
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:-
25985edc 2828* return true on success and STATUS_FAILURE on fail.
f8942e07
SH
2829*/
2830
093abf11
KM
2831INT BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter,
2832 PUINT pBuffer,
2833 FLASH2X_SECTION_VAL eFlash2xSectionVal,
2834 UINT uiOffsetWithinSectionVal,
2835 UINT uiNumBytes)
f8942e07 2836{
f8942e07
SH
2837 INT Status = STATUS_SUCCESS;
2838 INT SectionStartOffset = 0;
093abf11
KM
2839 UINT uiAbsoluteOffset = 0;
2840 UINT uiTemp = 0, value = 0;
2841
a2940b63 2842 if (Adapter == NULL) {
093abf11 2843 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
f8942e07
SH
2844 return -EINVAL;
2845 }
a2940b63 2846 if (Adapter->device_removed) {
093abf11 2847 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
f8942e07
SH
2848 return -ENODEV;
2849 }
2850
2851 //NO_SECTION_VAL means absolute offset is given.
093abf11 2852 if (eFlash2xSectionVal == NO_SECTION_VAL)
f8942e07
SH
2853 SectionStartOffset = 0;
2854 else
093abf11 2855 SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
f8942e07 2856
a2940b63 2857 if (SectionStartOffset == STATUS_FAILURE) {
093abf11 2858 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash 2.x Map ", eFlash2xSectionVal);
f8942e07
SH
2859 return -EINVAL;
2860 }
2861
093abf11
KM
2862 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
2863 return vendorextnReadSection(Adapter, (PUCHAR)pBuffer, eFlash2xSectionVal, uiOffsetWithinSectionVal, uiNumBytes);
f8942e07
SH
2864
2865 //calculating the absolute offset from FLASH;
2866 uiAbsoluteOffset = uiOffsetWithinSectionVal + SectionStartOffset;
2867 rdmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
2868 value = 0;
093abf11
KM
2869 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
2870 Status = BeceemFlashBulkRead(Adapter, pBuffer, uiAbsoluteOffset, uiNumBytes);
f8942e07 2871 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
a2940b63 2872 if (Status) {
093abf11
KM
2873 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Read Failed with Status :%d", Status);
2874 return Status;
f8942e07
SH
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:-
25985edc 2889* return true on success and STATUS_FAILURE on fail.
f8942e07
SH
2890*
2891*/
2892
093abf11
KM
2893INT BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter,
2894 PUINT pBuffer,
2895 FLASH2X_SECTION_VAL eFlash2xSectVal,
2896 UINT uiOffset,
2897 UINT uiNumBytes,
2898 UINT bVerify)
f8942e07 2899{
093abf11 2900 INT Status = STATUS_SUCCESS;
f8942e07
SH
2901 UINT FlashSectValStartOffset = 0;
2902 UINT uiTemp = 0, value = 0;
093abf11 2903
a2940b63 2904 if (Adapter == NULL) {
093abf11 2905 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Adapter structure is NULL");
f8942e07
SH
2906 return -EINVAL;
2907 }
093abf11 2908
a2940b63 2909 if (Adapter->device_removed) {
093abf11 2910 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device has been removed");
f8942e07
SH
2911 return -ENODEV;
2912 }
2913
2914 //NO_SECTION_VAL means absolute offset is given.
093abf11 2915 if (eFlash2xSectVal == NO_SECTION_VAL)
f8942e07
SH
2916 FlashSectValStartOffset = 0;
2917 else
093abf11 2918 FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal);
f8942e07 2919
a2940b63 2920 if (FlashSectValStartOffset == STATUS_FAILURE) {
093abf11 2921 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash Map 2.x", eFlash2xSectVal);
f8942e07
SH
2922 return -EINVAL;
2923 }
2924
093abf11 2925 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectVal))
f8942e07
SH
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;
093abf11 2933 wrmalt(Adapter, 0x0f000C80, &value, sizeof(value));
f8942e07 2934
093abf11 2935 Status = BeceemFlashBulkWrite(Adapter, pBuffer, uiOffset, uiNumBytes, bVerify);
f8942e07
SH
2936
2937 wrmalt(Adapter, 0x0f000C80, &uiTemp, sizeof(uiTemp));
a2940b63 2938 if (Status) {
093abf11
KM
2939 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Write failed with Status :%d", Status);
2940 return Status;
f8942e07
SH
2941 }
2942
2943 return Status;
f8942e07
SH
2944}
2945
f8942e07
SH
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:-
25985edc 2951* Return STATUS_SUCESS if get success in setting the right DSD else negaive error code
f8942e07
SH
2952*
2953**/
093abf11 2954
2979460d 2955static INT BcmGetActiveDSD(struct bcm_mini_adapter *Adapter)
f8942e07 2956{
093abf11 2957 FLASH2X_SECTION_VAL uiHighestPriDSD = 0;
f8942e07
SH
2958
2959 uiHighestPriDSD = getHighestPriDSD(Adapter);
2960 Adapter->eActiveDSD = uiHighestPriDSD;
2961
093abf11 2962 if (DSD0 == uiHighestPriDSD)
f8942e07 2963 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
093abf11 2964 if (DSD1 == uiHighestPriDSD)
f8942e07 2965 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
093abf11 2966 if (DSD2 == uiHighestPriDSD)
f8942e07 2967 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
093abf11
KM
2968 if (Adapter->eActiveDSD)
2969 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active DSD :%d", Adapter->eActiveDSD);
a2940b63 2970 if (Adapter->eActiveDSD == 0) {
f8942e07 2971 //if No DSD gets Active, Make Active the DSD with WR permission
a2940b63 2972 if (IsSectionWritable(Adapter, DSD2)) {
f8942e07
SH
2973 Adapter->eActiveDSD = DSD2;
2974 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD2Start;
a2940b63 2975 } else if (IsSectionWritable(Adapter, DSD1)) {
f8942e07
SH
2976 Adapter->eActiveDSD = DSD1;
2977 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSD1Start;
a2940b63 2978 } else if (IsSectionWritable(Adapter, DSD0)) {
f8942e07
SH
2979 Adapter->eActiveDSD = DSD0;
2980 Adapter->ulFlashCalStart = Adapter->psFlash2xCSInfo->OffsetFromZeroForDSDStart;
2981 }
2982 }
2983
2984 return STATUS_SUCCESS;
2985}
2986
f8942e07
SH
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
2979460d 2997static INT BcmGetActiveISO(struct bcm_mini_adapter *Adapter)
f8942e07 2998{
093abf11 2999 INT HighestPriISO = 0;
f8942e07 3000
f8942e07
SH
3001 HighestPriISO = getHighestPriISO(Adapter);
3002
093abf11
KM
3003 Adapter->eActiveISO = HighestPriISO;
3004 if (Adapter->eActiveISO == ISO_IMAGE2)
f8942e07 3005 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start);
093abf11 3006 else if (Adapter->eActiveISO == ISO_IMAGE1)
f8942e07
SH
3007 Adapter->uiActiveISOOffset = (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start);
3008
093abf11
KM
3009 if (Adapter->eActiveISO)
3010 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Active ISO :%x", Adapter->eActiveISO);
f8942e07
SH
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:-
25985edc 3021* Success:-TRUE , offset is writable
f8942e07
SH
3022* Failure:-FALSE, offset is RO
3023*
3024**/
093abf11 3025
2979460d 3026B_UINT8 IsOffsetWritable(struct bcm_mini_adapter *Adapter, UINT uiOffset)
f8942e07
SH
3027{
3028 UINT uiSectorNum = 0;
093abf11 3029 UINT uiWordOfSectorPermission = 0;
f8942e07
SH
3030 UINT uiBitofSectorePermission = 0;
3031 B_UINT32 permissionBits = 0;
093abf11 3032
f8942e07
SH
3033 uiSectorNum = uiOffset/Adapter->uiSectorSize;
3034
093abf11
KM
3035 // calculating the word having this Sector Access permission from SectorAccessBitMap Array
3036 uiWordOfSectorPermission = Adapter->psFlash2xCSInfo->SectorAccessBitMap[uiSectorNum / 16];
f8942e07 3037
093abf11
KM
3038 // calculating the bit index inside the word for this sector
3039 uiBitofSectorePermission = 2 * (15 - uiSectorNum % 16);
f8942e07 3040
093abf11
KM
3041 // Setting Access permission
3042 permissionBits = uiWordOfSectorPermission & (0x3 << uiBitofSectorePermission);
f8942e07 3043 permissionBits = (permissionBits >> uiBitofSectorePermission) & 0x3;
093abf11
KM
3044 if (permissionBits == SECTOR_READWRITE_PERMISSION)
3045 return TRUE;
f8942e07
SH
3046 else
3047 return FALSE;
3048}
3049
44a17eff 3050static INT BcmDumpFlash2xSectionBitMap(PFLASH2X_BITMAP psFlash2xBitMap)
f8942e07 3051{
2979460d 3052 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
093abf11
KM
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);
f8942e07
SH
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:-
25985edc 3081* Success:- STATUS_SUCESS
f8942e07
SH
3082* Failure:- negative error code
3083**/
3084
2979460d 3085INT BcmGetFlash2xSectionalBitMap(struct bcm_mini_adapter *Adapter, PFLASH2X_BITMAP psFlash2xBitMap)
f8942e07 3086{
f8942e07 3087 PFLASH2X_CS_INFO psFlash2xCSInfo = Adapter->psFlash2xCSInfo;
093abf11
KM
3088 FLASH2X_SECTION_VAL uiHighestPriDSD = 0;
3089 FLASH2X_SECTION_VAL uiHighestPriISO = 0;
3090 BOOLEAN SetActiveDSDDone = FALSE;
3091 BOOLEAN SetActiveISODone = FALSE;
f8942e07 3092
093abf11
KM
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.
a2940b63 3095 if (IsFlash2x(Adapter) == FALSE) {
f8942e07
SH
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)
093abf11
KM
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;
f8942e07 3109
093abf11 3110 return STATUS_SUCCESS;
f8942e07
SH
3111 }
3112
3113 uiHighestPriDSD = getHighestPriDSD(Adapter);
3114 uiHighestPriISO = getHighestPriISO(Adapter);
3115
3116 ///
3117 // IS0 IMAGE 2
3118 ///
a2940b63 3119 if ((psFlash2xCSInfo->OffsetISOImage2Part1Start) != UNINIT_PTR_IN_CS) {
f8942e07 3120 //Setting the 0th Bit representing the Section is present or not.
093abf11 3121 psFlash2xBitMap->ISO_IMAGE2 = psFlash2xBitMap->ISO_IMAGE2 | FLASH2X_SECTION_PRESENT;
f8942e07 3122
093abf11 3123 if (ReadISOSignature(Adapter, ISO_IMAGE2) == ISO_IMAGE_MAGIC_NUMBER)
f8942e07
SH
3124 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_VALID;
3125
093abf11
KM
3126 // Calculation for extrating the Access permission
3127 if (IsSectionWritable(Adapter, ISO_IMAGE2) == FALSE)
f8942e07
SH
3128 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_RO;
3129
a2940b63 3130 if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE2) {
093abf11 3131 psFlash2xBitMap->ISO_IMAGE2 |= FLASH2X_SECTION_ACT;
f8942e07
SH
3132 SetActiveISODone = TRUE;
3133 }
f8942e07
SH
3134 }
3135
3136 ///
3137 // IS0 IMAGE 1
3138 ///
a2940b63 3139 if ((psFlash2xCSInfo->OffsetISOImage1Part1Start) != UNINIT_PTR_IN_CS) {
093abf11 3140 // Setting the 0th Bit representing the Section is present or not.
f8942e07
SH
3141 psFlash2xBitMap->ISO_IMAGE1 = psFlash2xBitMap->ISO_IMAGE1 | FLASH2X_SECTION_PRESENT;
3142
093abf11 3143 if (ReadISOSignature(Adapter, ISO_IMAGE1) == ISO_IMAGE_MAGIC_NUMBER)
f8942e07
SH
3144 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_VALID;
3145
093abf11
KM
3146 // Calculation for extrating the Access permission
3147 if (IsSectionWritable(Adapter, ISO_IMAGE1) == FALSE)
f8942e07
SH
3148 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_RO;
3149
a2940b63 3150 if (SetActiveISODone == FALSE && uiHighestPriISO == ISO_IMAGE1) {
093abf11 3151 psFlash2xBitMap->ISO_IMAGE1 |= FLASH2X_SECTION_ACT;
f8942e07
SH
3152 SetActiveISODone = TRUE;
3153 }
3154 }
3155
f8942e07
SH
3156 ///
3157 // DSD2
3158 ///
a2940b63 3159 if ((psFlash2xCSInfo->OffsetFromZeroForDSD2Start) != UNINIT_PTR_IN_CS) {
f8942e07 3160 //Setting the 0th Bit representing the Section is present or not.
093abf11 3161 psFlash2xBitMap->DSD2 = psFlash2xBitMap->DSD2 | FLASH2X_SECTION_PRESENT;
f8942e07 3162
093abf11 3163 if (ReadDSDSignature(Adapter, DSD2) == DSD_IMAGE_MAGIC_NUMBER)
f8942e07
SH
3164 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_VALID;
3165
093abf11 3166 // Calculation for extrating the Access permission
a2940b63 3167 if (IsSectionWritable(Adapter, DSD2) == FALSE) {
f8942e07 3168 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_RO;
a2940b63 3169 } else {
f8942e07 3170 //Means section is writable
a2940b63 3171 if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD2)) {
093abf11
KM
3172 psFlash2xBitMap->DSD2 |= FLASH2X_SECTION_ACT;
3173 SetActiveDSDDone = TRUE;
f8942e07
SH
3174 }
3175 }
3176 }
3177
3178 ///
3179 // DSD 1
3180 ///
a2940b63 3181 if ((psFlash2xCSInfo->OffsetFromZeroForDSD1Start) != UNINIT_PTR_IN_CS) {
093abf11
KM
3182 // Setting the 0th Bit representing the Section is present or not.
3183 psFlash2xBitMap->DSD1 = psFlash2xBitMap->DSD1 | FLASH2X_SECTION_PRESENT;
f8942e07 3184
093abf11 3185 if (ReadDSDSignature(Adapter, DSD1) == DSD_IMAGE_MAGIC_NUMBER)
f8942e07
SH
3186 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_VALID;
3187
093abf11 3188 // Calculation for extrating the Access permission
a2940b63 3189 if (IsSectionWritable(Adapter, DSD1) == FALSE) {
f8942e07 3190 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_RO;
a2940b63 3191 } else {
093abf11 3192 // Means section is writable
a2940b63 3193 if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD1)) {
093abf11
KM
3194 psFlash2xBitMap->DSD1 |= FLASH2X_SECTION_ACT;
3195 SetActiveDSDDone = TRUE;
f8942e07
SH
3196 }
3197 }
f8942e07
SH
3198 }
3199
3200 ///
3201 //For DSD 0
3202 //
a2940b63 3203 if ((psFlash2xCSInfo->OffsetFromZeroForDSDStart) != UNINIT_PTR_IN_CS) {
f8942e07
SH
3204 //Setting the 0th Bit representing the Section is present or not.
3205 psFlash2xBitMap->DSD0 = psFlash2xBitMap->DSD0 | FLASH2X_SECTION_PRESENT;
3206
093abf11 3207 if (ReadDSDSignature(Adapter, DSD0) == DSD_IMAGE_MAGIC_NUMBER)
f8942e07
SH
3208 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_VALID;
3209
093abf11 3210 // Setting Access permission
a2940b63 3211 if (IsSectionWritable(Adapter, DSD0) == FALSE) {
f8942e07 3212 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_RO;
a2940b63 3213 } else {
093abf11 3214 // Means section is writable
a2940b63 3215 if ((SetActiveDSDDone == FALSE) && (uiHighestPriDSD == DSD0)) {
093abf11
KM
3216 psFlash2xBitMap->DSD0 |= FLASH2X_SECTION_ACT;
3217 SetActiveDSDDone = TRUE;
f8942e07
SH
3218 }
3219 }
3220 }
3221
3222 ///
093abf11 3223 // VSA 0
f8942e07 3224 ///
a2940b63 3225 if ((psFlash2xCSInfo->OffsetFromZeroForVSAStart) != UNINIT_PTR_IN_CS) {
093abf11
KM
3226 // Setting the 0th Bit representing the Section is present or not.
3227 psFlash2xBitMap->VSA0 = psFlash2xBitMap->VSA0 | FLASH2X_SECTION_PRESENT;
f8942e07 3228
093abf11 3229 // Setting the Access Bit. Map is not defined hece setting it always valid
f8942e07
SH
3230 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_VALID;
3231
093abf11
KM
3232 // Calculation for extrating the Access permission
3233 if (IsSectionWritable(Adapter, VSA0) == FALSE)
f8942e07
SH
3234 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_RO;
3235
093abf11
KM
3236 // By Default section is Active
3237 psFlash2xBitMap->VSA0 |= FLASH2X_SECTION_ACT;
f8942e07
SH
3238 }
3239
f8942e07 3240 ///
093abf11 3241 // VSA 1
f8942e07 3242 ///
a2940b63 3243 if ((psFlash2xCSInfo->OffsetFromZeroForVSA1Start) != UNINIT_PTR_IN_CS) {
093abf11
KM
3244 // Setting the 0th Bit representing the Section is present or not.
3245 psFlash2xBitMap->VSA1 = psFlash2xBitMap->VSA1 | FLASH2X_SECTION_PRESENT;
f8942e07 3246
093abf11
KM
3247 // Setting the Access Bit. Map is not defined hece setting it always valid
3248 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_VALID;
f8942e07 3249
093abf11
KM
3250 // Checking For Access permission
3251 if (IsSectionWritable(Adapter, VSA1) == FALSE)
f8942e07
SH
3252 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_RO;
3253
093abf11
KM
3254 // By Default section is Active
3255 psFlash2xBitMap->VSA1 |= FLASH2X_SECTION_ACT;
f8942e07
SH
3256 }
3257
f8942e07 3258 ///
093abf11 3259 // VSA 2
f8942e07 3260 ///
a2940b63 3261 if ((psFlash2xCSInfo->OffsetFromZeroForVSA2Start) != UNINIT_PTR_IN_CS) {
093abf11
KM
3262 // Setting the 0th Bit representing the Section is present or not.
3263 psFlash2xBitMap->VSA2 = psFlash2xBitMap->VSA2 | FLASH2X_SECTION_PRESENT;
f8942e07 3264
093abf11 3265 // Setting the Access Bit. Map is not defined hece setting it always valid
f8942e07
SH
3266 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_VALID;
3267
093abf11
KM
3268 // Checking For Access permission
3269 if (IsSectionWritable(Adapter, VSA2) == FALSE)
f8942e07
SH
3270 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_RO;
3271
093abf11
KM
3272 // By Default section is Active
3273 psFlash2xBitMap->VSA2 |= FLASH2X_SECTION_ACT;
f8942e07
SH
3274 }
3275
3276 ///
3277 // SCSI Section
3278 ///
a2940b63 3279 if ((psFlash2xCSInfo->OffsetFromZeroForScsiFirmware) != UNINIT_PTR_IN_CS) {
093abf11
KM
3280 // Setting the 0th Bit representing the Section is present or not.
3281 psFlash2xBitMap->SCSI = psFlash2xBitMap->SCSI | FLASH2X_SECTION_PRESENT;
f8942e07 3282
093abf11
KM
3283 // Setting the Access Bit. Map is not defined hece setting it always valid
3284 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_VALID;
f8942e07 3285
093abf11
KM
3286 // Checking For Access permission
3287 if (IsSectionWritable(Adapter, SCSI) == FALSE)
f8942e07
SH
3288 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_RO;
3289
093abf11
KM
3290 // By Default section is Active
3291 psFlash2xBitMap->SCSI |= FLASH2X_SECTION_ACT;
f8942e07
SH
3292 }
3293
f8942e07 3294 ///
093abf11 3295 // Control Section
f8942e07 3296 ///
a2940b63 3297 if ((psFlash2xCSInfo->OffsetFromZeroForControlSectionStart) != UNINIT_PTR_IN_CS) {
093abf11 3298 // Setting the 0th Bit representing the Section is present or not.
f8942e07
SH
3299 psFlash2xBitMap->CONTROL_SECTION = psFlash2xBitMap->CONTROL_SECTION | (FLASH2X_SECTION_PRESENT);
3300
093abf11 3301 // Setting the Access Bit. Map is not defined hece setting it always valid
f8942e07
SH
3302 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_VALID;
3303
093abf11
KM
3304 // Checking For Access permission
3305 if (IsSectionWritable(Adapter, CONTROL_SECTION) == FALSE)
f8942e07
SH
3306 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_RO;
3307
093abf11
KM
3308 // By Default section is Active
3309 psFlash2xBitMap->CONTROL_SECTION |= FLASH2X_SECTION_ACT;
f8942e07
SH
3310 }
3311
3312 ///
093abf11 3313 // For Reserved Sections
f8942e07
SH
3314 ///
3315 psFlash2xBitMap->Reserved0 = 0;
3316 psFlash2xBitMap->Reserved0 = 0;
3317 psFlash2xBitMap->Reserved0 = 0;
f8942e07
SH
3318 BcmDumpFlash2xSectionBitMap(psFlash2xBitMap);
3319
093abf11 3320 return STATUS_SUCCESS;
f8942e07 3321}
093abf11 3322
f8942e07
SH
3323/**
3324BcmSetActiveSection :- 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
3330Return Value:- Make the priorit highest else return erorr code
3331
3332**/
093abf11 3333
2979460d 3334INT BcmSetActiveSection(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectVal)
f8942e07 3335{
44a17eff 3336 unsigned int SectImagePriority = 0;
093abf11 3337 INT Status = STATUS_SUCCESS;
f8942e07
SH
3338
3339 //DSD_HEADER sDSD = {0};
3340 //ISO_HEADER sISO = {0};
3341 INT HighestPriDSD = 0 ;
3342 INT HighestPriISO = 0;
3343
093abf11 3344 Status = IsSectionWritable(Adapter, eFlash2xSectVal);
a2940b63 3345 if (Status != TRUE) {
093abf11 3346 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section <%d> is not writable", eFlash2xSectVal);
f8942e07
SH
3347 return STATUS_FAILURE;
3348 }
3349
093abf11 3350 Adapter->bHeaderChangeAllowed = TRUE;
a2940b63
KM
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
f8942e07
SH
3383 HighestPriISO = getHighestPriISO(Adapter);
3384
a2940b63 3385 if (HighestPriISO == eFlash2xSectVal) {
093abf11
KM
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;
f8942e07
SH
3388 break;
3389 }
3390
a2940b63
KM
3391 SectImagePriority = 2;
3392 }
f8942e07 3393
a2940b63 3394 SectImagePriority = htonl(SectImagePriority);
f8942e07 3395
a2940b63
KM
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 }
f8942e07 3422
a2940b63
KM
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);
f8942e07
SH
3430
3431 Status = BcmFlash2xBulkWrite(Adapter,
093abf11 3432 &SectImagePriority,
a2940b63
KM
3433 HighestPriDSD,
3434 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
093abf11
KM
3435 SIGNATURE_SIZE,
3436 TRUE);
a2940b63 3437 if (Status) {
093abf11
KM
3438 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
3439 break;
f8942e07 3440 }
a2940b63 3441
f8942e07 3442 HighestPriDSD = getHighestPriDSD(Adapter);
a2940b63
KM
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);
093abf11 3446 Status = STATUS_SUCCESS;
f8942e07
SH
3447 break;
3448 }
3449
a2940b63 3450 SectImagePriority = htonl(0x2);
f8942e07 3451 Status = BcmFlash2xBulkWrite(Adapter,
093abf11 3452 &SectImagePriority,
a2940b63 3453 HighestPriDSD,
093abf11
KM
3454 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
3455 SIGNATURE_SIZE,
3456 TRUE);
a2940b63 3457 if (Status) {
093abf11 3458 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Priority has not been written properly");
093abf11 3459 break;
f8942e07 3460 }
a2940b63
KM
3461
3462 HighestPriDSD = getHighestPriDSD(Adapter);
3463 if ((HighestPriDSD == eFlash2xSectVal)) {
3464 Status = STATUS_SUCCESS;
3465 break;
3466 }
3467
3468 SectImagePriority = 3;
f8942e07 3469 }
a2940b63
KM
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");
093abf11 3479 Status = STATUS_FAILURE;
f8942e07
SH
3480 break;
3481 }
a2940b63
KM
3482 } else {
3483 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Signature is currupted. Hence can't increase the priority");
093abf11
KM
3484 Status = STATUS_FAILURE;
3485 break;
a2940b63
KM
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;
f8942e07
SH
3496 }
3497
093abf11 3498 Adapter->bHeaderChangeAllowed = FALSE;
f8942e07 3499 return Status;
f8942e07
SH
3500}
3501
3502/**
3503BcmCopyISO - Used only for copying the ISO section
3504@Adapater :- Bcm Driver Private Data Structure
3505@sCopySectStrut :- Section copy structure
3506
3507Return value:- SUCCESS if copies successfully else negative error code
3508
3509**/
093abf11 3510
2979460d 3511INT BcmCopyISO(struct bcm_mini_adapter *Adapter, FLASH2X_COPY_SECTION sCopySectStrut)
f8942e07 3512{
f8942e07 3513 PCHAR Buff = NULL;
093abf11 3514 FLASH2X_SECTION_VAL eISOReadPart = 0, eISOWritePart = 0;
f8942e07
SH
3515 UINT uiReadOffsetWithinPart = 0, uiWriteOffsetWithinPart = 0;
3516 UINT uiTotalDataToCopy = 0;
093abf11 3517 BOOLEAN IsThisHeaderSector = FALSE;
f8942e07
SH
3518 UINT sigOffset = 0;
3519 UINT ISOLength = 0;
3520 UINT Status = STATUS_SUCCESS;
3521 UINT SigBuff[MAX_RW_SIZE];
3522 UINT i = 0;
3523
a2940b63 3524 if (ReadISOSignature(Adapter, sCopySectStrut.SrcSection) != ISO_IMAGE_MAGIC_NUMBER) {
093abf11 3525 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
f8942e07
SH
3526 return STATUS_FAILURE;
3527 }
3528
3529 Status = BcmFlash2xBulkRead(Adapter,
093abf11
KM
3530 &ISOLength,
3531 sCopySectStrut.SrcSection,
3532 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageSize),
3533 4);
a2940b63 3534 if (Status) {
093abf11 3535 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO\n");
f8942e07
SH
3536 return Status;
3537 }
3538
3539 ISOLength = htonl(ISOLength);
093abf11 3540 if (ISOLength % Adapter->uiSectorSize)
093abf11 3541 ISOLength = Adapter->uiSectorSize * (1 + ISOLength/Adapter->uiSectorSize);
f8942e07
SH
3542
3543 sigOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);
3544
3545 Buff = kzalloc(Adapter->uiSectorSize, GFP_KERNEL);
3546
a2940b63 3547 if (Buff == NULL) {
093abf11
KM
3548 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for section size");
3549 return -ENOMEM;
f8942e07
SH
3550 }
3551
a2940b63 3552 if (sCopySectStrut.SrcSection == ISO_IMAGE1 && sCopySectStrut.DstSection == ISO_IMAGE2) {
093abf11
KM
3553 eISOReadPart = ISO_IMAGE1;
3554 eISOWritePart = ISO_IMAGE2;
f8942e07 3555 uiReadOffsetWithinPart = 0;
093abf11 3556 uiWriteOffsetWithinPart = 0;
f8942e07 3557
093abf11
KM
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);
f8942e07 3564
a2940b63 3565 if (uiTotalDataToCopy < ISOLength) {
093abf11 3566 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
e5969d55
JL
3567 Status = STATUS_FAILURE;
3568 goto out;
f8942e07
SH
3569 }
3570
093abf11
KM
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);
f8942e07 3577
a2940b63 3578 if (uiTotalDataToCopy < ISOLength) {
093abf11 3579 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
e5969d55
JL
3580 Status = STATUS_FAILURE;
3581 goto out;
f8942e07
SH
3582 }
3583
3584 uiTotalDataToCopy = ISOLength;
3585
093abf11 3586 CorruptISOSig(Adapter, ISO_IMAGE2);
a2940b63
KM
3587 while (uiTotalDataToCopy) {
3588 if (uiTotalDataToCopy == Adapter->uiSectorSize) {
093abf11
KM
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;
f8942e07
SH
3592 uiReadOffsetWithinPart = 0;
3593 eISOWritePart = ISO_IMAGE2;
093abf11
KM
3594 uiWriteOffsetWithinPart = 0;
3595 IsThisHeaderSector = TRUE;
a2940b63 3596 } else {
093abf11
KM
3597 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3598 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
f8942e07 3599
a2940b63 3600 if ((eISOReadPart == ISO_IMAGE1) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
093abf11 3601 eISOReadPart = ISO_IMAGE1_PART2;
f8942e07
SH
3602 uiReadOffsetWithinPart = 0;
3603 }
093abf11 3604
a2940b63 3605 if ((eISOReadPart == ISO_IMAGE1_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
093abf11 3606 eISOReadPart = ISO_IMAGE1_PART3;
f8942e07
SH
3607 uiReadOffsetWithinPart = 0;
3608 }
093abf11 3609
a2940b63 3610 if ((eISOWritePart == ISO_IMAGE2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
093abf11 3611 eISOWritePart = ISO_IMAGE2_PART2;
f8942e07
SH
3612 uiWriteOffsetWithinPart = 0;
3613 }
093abf11 3614
a2940b63 3615 if ((eISOWritePart == ISO_IMAGE2_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
093abf11 3616 eISOWritePart = ISO_IMAGE2_PART3;
f8942e07
SH
3617 uiWriteOffsetWithinPart = 0;
3618 }
3619 }
3620
3621 Status = BcmFlash2xBulkRead(Adapter,
093abf11
KM
3622 (PUINT)Buff,
3623 eISOReadPart,
3624 uiReadOffsetWithinPart,
3625 Adapter->uiSectorSize);
a2940b63 3626 if (Status) {
093abf11 3627 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
f8942e07
SH
3628 break;
3629 }
3630
a2940b63 3631 if (IsThisHeaderSector == TRUE) {
093abf11 3632 // If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
f8942e07
SH
3633 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
3634
093abf11 3635 for (i = 0; i < MAX_RW_SIZE; i++)
f8942e07
SH
3636 *(Buff + sigOffset + i) = 0xFF;
3637 }
093abf11 3638 Adapter->bHeaderChangeAllowed = TRUE;
f8942e07 3639 Status = BcmFlash2xBulkWrite(Adapter,
093abf11
KM
3640 (PUINT)Buff,
3641 eISOWritePart,
3642 uiWriteOffsetWithinPart,
3643 Adapter->uiSectorSize,
3644 TRUE);
a2940b63 3645 if (Status) {
093abf11 3646 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
f8942e07
SH
3647 break;
3648 }
3649
3650 Adapter->bHeaderChangeAllowed = FALSE;
a2940b63 3651 if (IsThisHeaderSector == TRUE) {
f8942e07 3652 WriteToFlashWithoutSectorErase(Adapter,
093abf11
KM
3653 SigBuff,
3654 eISOWritePart,
3655 sigOffset,
3656 MAX_RW_SIZE);
3657 IsThisHeaderSector = FALSE;
f8942e07 3658 }
25985edc 3659 //subtracting the written Data
093abf11 3660 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
f8942e07 3661 }
f8942e07
SH
3662 }
3663
a2940b63 3664 if (sCopySectStrut.SrcSection == ISO_IMAGE2 && sCopySectStrut.DstSection == ISO_IMAGE1) {
093abf11
KM
3665 eISOReadPart = ISO_IMAGE2;
3666 eISOWritePart = ISO_IMAGE1;
3667 uiReadOffsetWithinPart = 0;
3668 uiWriteOffsetWithinPart = 0;
f8942e07 3669
093abf11
KM
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);
f8942e07 3676
a2940b63 3677 if (uiTotalDataToCopy < ISOLength) {
093abf11 3678 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Source ISO Section does not have valid signature");
e5969d55
JL
3679 Status = STATUS_FAILURE;
3680 goto out;
f8942e07
SH
3681 }
3682
093abf11
KM
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);
f8942e07 3689
a2940b63 3690 if (uiTotalDataToCopy < ISOLength) {
093abf11 3691 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "error as Dest ISO Section does not have enough section size");
e5969d55
JL
3692 Status = STATUS_FAILURE;
3693 goto out;
f8942e07
SH
3694 }
3695
3696 uiTotalDataToCopy = ISOLength;
3697
093abf11 3698 CorruptISOSig(Adapter, ISO_IMAGE1);
f8942e07 3699
a2940b63
KM
3700 while (uiTotalDataToCopy) {
3701 if (uiTotalDataToCopy == Adapter->uiSectorSize) {
f8942e07 3702 //Setting for write of first sector. First sector is assumed to be written in last
093abf11
KM
3703 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Writing the signature sector");
3704 eISOReadPart = ISO_IMAGE2;
f8942e07
SH
3705 uiReadOffsetWithinPart = 0;
3706 eISOWritePart = ISO_IMAGE1;
093abf11 3707 uiWriteOffsetWithinPart = 0;
f8942e07 3708 IsThisHeaderSector = TRUE;
a2940b63 3709 } else {
093abf11
KM
3710 uiReadOffsetWithinPart = uiReadOffsetWithinPart + Adapter->uiSectorSize;
3711 uiWriteOffsetWithinPart = uiWriteOffsetWithinPart + Adapter->uiSectorSize;
f8942e07 3712
a2940b63 3713 if ((eISOReadPart == ISO_IMAGE2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part1Start))) {
093abf11 3714 eISOReadPart = ISO_IMAGE2_PART2;
f8942e07
SH
3715 uiReadOffsetWithinPart = 0;
3716 }
093abf11 3717
a2940b63 3718 if ((eISOReadPart == ISO_IMAGE2_PART2) && (uiReadOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage2Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage2Part2Start))) {
093abf11 3719 eISOReadPart = ISO_IMAGE2_PART3;
f8942e07
SH
3720 uiReadOffsetWithinPart = 0;
3721 }
093abf11 3722
a2940b63 3723 if ((eISOWritePart == ISO_IMAGE1) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part1Start))) {
093abf11 3724 eISOWritePart = ISO_IMAGE1_PART2;
f8942e07
SH
3725 uiWriteOffsetWithinPart = 0;
3726 }
093abf11 3727
a2940b63 3728 if ((eISOWritePart == ISO_IMAGE1_PART2) && (uiWriteOffsetWithinPart == (Adapter->psFlash2xCSInfo->OffsetISOImage1Part2End - Adapter->psFlash2xCSInfo->OffsetISOImage1Part2Start))) {
093abf11 3729 eISOWritePart = ISO_IMAGE1_PART3;
f8942e07
SH
3730 uiWriteOffsetWithinPart = 0;
3731 }
3732 }
3733
3734 Status = BcmFlash2xBulkRead(Adapter,
093abf11
KM
3735 (PUINT)Buff,
3736 eISOReadPart,
3737 uiReadOffsetWithinPart,
3738 Adapter->uiSectorSize);
a2940b63 3739 if (Status) {
093abf11 3740 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOReadPart, uiReadOffsetWithinPart);
f8942e07
SH
3741 break;
3742 }
3743
a2940b63 3744 if (IsThisHeaderSector == TRUE) {
093abf11 3745 // If this is header sector write 0xFFFFFFFF at the sig time and in last write sig
f8942e07
SH
3746 memcpy(SigBuff, Buff + sigOffset, MAX_RW_SIZE);
3747
093abf11 3748 for (i = 0; i < MAX_RW_SIZE; i++)
f8942e07 3749 *(Buff + sigOffset + i) = 0xFF;
f8942e07 3750 }
093abf11 3751 Adapter->bHeaderChangeAllowed = TRUE;
f8942e07 3752 Status = BcmFlash2xBulkWrite(Adapter,
093abf11
KM
3753 (PUINT)Buff,
3754 eISOWritePart,
3755 uiWriteOffsetWithinPart,
3756 Adapter->uiSectorSize,
3757 TRUE);
a2940b63 3758 if (Status) {
093abf11 3759 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed while copying ISO: Part: %x, OffsetWithinPart: %x\n", eISOWritePart, uiWriteOffsetWithinPart);
f8942e07
SH
3760 break;
3761 }
3762
093abf11 3763 Adapter->bHeaderChangeAllowed = FALSE;
a2940b63 3764 if (IsThisHeaderSector == TRUE) {
f8942e07 3765 WriteToFlashWithoutSectorErase(Adapter,
093abf11
KM
3766 SigBuff,
3767 eISOWritePart,
3768 sigOffset,
3769 MAX_RW_SIZE);
3770
3771 IsThisHeaderSector = FALSE;
f8942e07
SH
3772 }
3773
093abf11
KM
3774 // subtracting the written Data
3775 uiTotalDataToCopy = uiTotalDataToCopy - Adapter->uiSectorSize;
f8942e07 3776 }
f8942e07 3777 }
e5969d55 3778out:
082e889b 3779 kfree(Buff);
f8942e07
SH
3780
3781 return Status;
3782}
093abf11 3783
f8942e07
SH
3784/**
3785BcmFlash2xCorruptSig : 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
3790Return Value :-
25985edc 3791 Success :- If Section is present and writable, corrupt the sig and return STATUS_SUCCESS
f8942e07
SH
3792 Failure :-Return negative error code
3793
3794
3795**/
093abf11 3796
2979460d 3797INT BcmFlash2xCorruptSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
f8942e07 3798{
093abf11 3799 INT Status = STATUS_SUCCESS;
f8942e07 3800
093abf11 3801 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section Value :%x\n", eFlash2xSectionVal);
f8942e07 3802
a2940b63 3803 if ((eFlash2xSectionVal == DSD0) || (eFlash2xSectionVal == DSD1) || (eFlash2xSectionVal == DSD2)) {
f8942e07 3804 Status = CorruptDSDSig(Adapter, eFlash2xSectionVal);
a2940b63 3805 } else if (eFlash2xSectionVal == ISO_IMAGE1 || eFlash2xSectionVal == ISO_IMAGE2) {
f8942e07 3806 Status = CorruptISOSig(Adapter, eFlash2xSectionVal);
a2940b63 3807 } else {
093abf11 3808 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Given Section <%d>does not have Header", eFlash2xSectionVal);
f8942e07
SH
3809 return STATUS_SUCCESS;
3810 }
3811 return Status;
3812}
093abf11 3813
f8942e07
SH
3814/**
3815BcmFlash2xWriteSig :-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
3820Return Value :-
25985edc 3821 Success :- If Section is present and writable write the sig and return STATUS_SUCCESS
f8942e07
SH
3822 Failure :-Return negative error code
3823
3824**/
093abf11 3825
2979460d 3826INT BcmFlash2xWriteSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlashSectionVal)
f8942e07 3827{
093abf11 3828 UINT uiSignature = 0;
f8942e07 3829 UINT uiOffset = 0;
f8942e07 3830
093abf11 3831 // DSD_HEADER dsdHeader = {0};
a2940b63 3832 if (Adapter->bSigCorrupted == FALSE) {
093abf11 3833 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Signature is not corrupted by driver, hence not restoring\n");
f8942e07
SH
3834 return STATUS_SUCCESS;
3835 }
093abf11 3836
a2940b63
KM
3837 if (Adapter->bAllDSDWriteAllow == FALSE) {
3838 if (IsSectionWritable(Adapter, eFlashSectionVal) == FALSE) {
093abf11 3839 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Write signature");
f8942e07
SH
3840 return SECTOR_IS_NOT_WRITABLE;
3841 }
3842 }
093abf11 3843
a2940b63 3844 if ((eFlashSectionVal == DSD0) || (eFlashSectionVal == DSD1) || (eFlashSectionVal == DSD2)) {
093abf11
KM
3845 uiSignature = htonl(DSD_IMAGE_MAGIC_NUMBER);
3846 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader;
f8942e07 3847
093abf11 3848 uiOffset += FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber);
f8942e07 3849
a2940b63 3850 if ((ReadDSDSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
093abf11 3851 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Corrupted Pattern is not there. Hence won't write sig");
f8942e07
SH
3852 return STATUS_FAILURE;
3853 }
a2940b63 3854 } else if ((eFlashSectionVal == ISO_IMAGE1) || (eFlashSectionVal == ISO_IMAGE2)) {
f8942e07 3855 uiSignature = htonl(ISO_IMAGE_MAGIC_NUMBER);
093abf11
KM
3856 // uiOffset = 0;
3857 uiOffset = FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImageMagicNumber);
a2940b63 3858 if ((ReadISOSignature(Adapter, eFlashSectionVal) & 0xFF000000) != CORRUPTED_PATTERN) {
093abf11 3859 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Currupted Pattern is not there. Hence won't write sig");
f8942e07
SH
3860 return STATUS_FAILURE;
3861 }
a2940b63 3862 } else {
093abf11 3863 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GIVEN SECTION< %d > IS NOT VALID FOR SIG WRITE...", eFlashSectionVal);
f8942e07
SH
3864 return STATUS_FAILURE;
3865 }
3866
093abf11 3867 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Restoring the signature");
f8942e07
SH
3868
3869 Adapter->bHeaderChangeAllowed = TRUE;
3870 Adapter->bSigCorrupted = FALSE;
093abf11 3871 BcmFlash2xBulkWrite(Adapter, &uiSignature, eFlashSectionVal, uiOffset, SIGNATURE_SIZE, TRUE);
f8942e07
SH
3872 Adapter->bHeaderChangeAllowed = FALSE;
3873
f8942e07
SH
3874 return STATUS_SUCCESS;
3875}
093abf11 3876
f8942e07
SH
3877/**
3878validateFlash2xReadWrite :- 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
3883Return values:-Return TRUE is request is valid else FALSE.
3884
3885
3886**/
093abf11
KM
3887
3888INT validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, PFLASH2X_READWRITE psFlash2xReadWrite)
f8942e07 3889{
093abf11
KM
3890 UINT uiNumOfBytes = 0;
3891 UINT uiSectStartOffset = 0;
f8942e07 3892 UINT uiSectEndOffset = 0;
093abf11 3893
f8942e07
SH
3894 uiNumOfBytes = psFlash2xReadWrite->numOfBytes;
3895
a2940b63 3896 if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) {
093abf11 3897 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exixt in Flash", psFlash2xReadWrite->Section);
f8942e07
SH
3898 return FALSE;
3899 }
093abf11
KM
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);
a2940b63
KM
3902 if ((psFlash2xReadWrite->Section == ISO_IMAGE1) || (psFlash2xReadWrite->Section == ISO_IMAGE2)) {
3903 if (psFlash2xReadWrite->Section == ISO_IMAGE1) {
093abf11
KM
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);
a2940b63 3910 } else if (psFlash2xReadWrite->Section == ISO_IMAGE2) {
093abf11
KM
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);
f8942e07
SH
3917 }
3918
093abf11
KM
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;
f8942e07 3922
093abf11 3923 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Total size of the ISO Image :%x", uiSectEndOffset);
a2940b63 3924 } else
093abf11
KM
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);
f8942e07 3928
093abf11
KM
3929 // Checking the boundary condition
3930 if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset)
f8942e07 3931 return TRUE;
a2940b63 3932 else {
093abf11 3933 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request....");
f8942e07
SH
3934 return FALSE;
3935 }
f8942e07
SH
3936}
3937
3938/**
3939IsFlash2x :- check for Flash 2.x
3940@Adapater :- Bcm Driver Private Data Structure
3941
3942Return value:-
3943 return TRUE if flah2.x of hgher version else return false.
3944**/
3945
2979460d 3946INT IsFlash2x(struct bcm_mini_adapter *Adapter)
f8942e07 3947{
093abf11
KM
3948 if (Adapter->uiFlashLayoutMajorVersion >= FLASH_2X_MAJOR_NUMBER)
3949 return TRUE;
f8942e07
SH
3950 else
3951 return FALSE;
3952}
093abf11 3953
f8942e07
SH
3954/**
3955GetFlashBaseAddr :- Calculate the Flash Base address
3956@Adapater :- Bcm Driver Private Data Structure
3957
3958Return Value:-
3959 Success :- Base Address of the Flash
3960**/
3961
2979460d 3962static INT GetFlashBaseAddr(struct bcm_mini_adapter *Adapter)
f8942e07 3963{
f8942e07
SH
3964 UINT uiBaseAddr = 0;
3965
a2940b63 3966 if (Adapter->bDDRInitDone) {
f8942e07 3967 /*
093abf11
KM
3968 For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3969 In case of Raw Read... use the default value
f8942e07 3970 */
093abf11
KM
3971 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
3972 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
3973 uiBaseAddr = Adapter->uiFlashBaseAdd;
f8942e07
SH
3974 else
3975 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT;
a2940b63 3976 } else {
f8942e07 3977 /*
093abf11
KM
3978 For All Valid Flash Versions... except 1.1, take the value from FlashBaseAddr
3979 In case of Raw Read... use the default value
f8942e07 3980 */
093abf11
KM
3981 if (Adapter->uiFlashLayoutMajorVersion && (Adapter->bFlashRawRead == FALSE) &&
3982 !((Adapter->uiFlashLayoutMajorVersion == 1) && (Adapter->uiFlashLayoutMinorVersion == 1)))
f8942e07
SH
3983 uiBaseAddr = Adapter->uiFlashBaseAdd | FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
3984 else
3985 uiBaseAddr = FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT;
3986 }
3987
093abf11 3988 return uiBaseAddr;
f8942e07 3989}
093abf11 3990
f8942e07
SH
3991/**
3992BcmCopySection :- 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
4002Return Values-
25985edc 4003 Success : Return STATUS_SUCCESS
f8942e07
SH
4004 Faillure :- return negative error code
4005
4006**/
4007
093abf11
KM
4008INT BcmCopySection(struct bcm_mini_adapter *Adapter,
4009 FLASH2X_SECTION_VAL SrcSection,
4010 FLASH2X_SECTION_VAL DstSection,
4011 UINT offset,
4012 UINT numOfBytes)
f8942e07 4013{
093abf11 4014 UINT BuffSize = 0;
f8942e07 4015 UINT BytesToBeCopied = 0;
093abf11
KM
4016 PUCHAR pBuff = NULL;
4017 INT Status = STATUS_SUCCESS;
4018
a2940b63 4019 if (SrcSection == DstSection) {
093abf11 4020 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source and Destination should be different ...try again");
f8942e07
SH
4021 return -EINVAL;
4022 }
093abf11 4023
a2940b63 4024 if ((SrcSection != DSD0) && (SrcSection != DSD1) && (SrcSection != DSD2)) {
093abf11
KM
4025 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source should be DSD subsection");
4026 return -EINVAL;
f8942e07 4027 }
093abf11 4028
a2940b63 4029 if ((DstSection != DSD0) && (DstSection != DSD1) && (DstSection != DSD2)) {
093abf11
KM
4030 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destination should be DSD subsection");
4031 return -EINVAL;
f8942e07
SH
4032 }
4033
093abf11 4034 // if offset zero means have to copy complete secton
a2940b63 4035 if (numOfBytes == 0) {
093abf11
KM
4036 numOfBytes = BcmGetSectionValEndOffset(Adapter, SrcSection)
4037 - BcmGetSectionValStartOffset(Adapter, SrcSection);
f8942e07 4038
093abf11 4039 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Section Size :0x%x", numOfBytes);
f8942e07
SH
4040 }
4041
093abf11 4042 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, SrcSection)
a2940b63 4043 - BcmGetSectionValStartOffset(Adapter, SrcSection)) {
093abf11
KM
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);
f8942e07
SH
4046 return -EINVAL;
4047 }
4048
093abf11 4049 if ((offset + numOfBytes) > BcmGetSectionValEndOffset(Adapter, DstSection)
a2940b63 4050 - BcmGetSectionValStartOffset(Adapter, DstSection)) {
093abf11
KM
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);
f8942e07
SH
4053 return -EINVAL;
4054 }
4055
093abf11 4056 if (numOfBytes > Adapter->uiSectorSize)
f8942e07
SH
4057 BuffSize = Adapter->uiSectorSize;
4058 else
093abf11 4059 BuffSize = numOfBytes;
f8942e07
SH
4060
4061 pBuff = (PCHAR)kzalloc(BuffSize, GFP_KERNEL);
a2940b63 4062 if (pBuff == NULL) {
093abf11 4063 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed.. ");
f8942e07
SH
4064 return -ENOMEM;
4065 }
4066
093abf11
KM
4067 BytesToBeCopied = Adapter->uiSectorSize;
4068 if (offset % Adapter->uiSectorSize)
f8942e07 4069 BytesToBeCopied = Adapter->uiSectorSize - (offset % Adapter->uiSectorSize);
093abf11
KM
4070 if (BytesToBeCopied > numOfBytes)
4071 BytesToBeCopied = numOfBytes;
f8942e07
SH
4072
4073 Adapter->bHeaderChangeAllowed = TRUE;
4074
a2940b63 4075 do {
093abf11 4076 Status = BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, SrcSection , offset, BytesToBeCopied);
a2940b63 4077 if (Status) {
093abf11 4078 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read failed at offset :%d for NOB :%d", SrcSection, BytesToBeCopied);
f8942e07
SH
4079 break;
4080 }
093abf11 4081 Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pBuff, DstSection, offset, BytesToBeCopied, FALSE);
a2940b63 4082 if (Status) {
093abf11 4083 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Write failed at offset :%d for NOB :%d", DstSection, BytesToBeCopied);
f8942e07
SH
4084 break;
4085 }
4086 offset = offset + BytesToBeCopied;
093abf11 4087 numOfBytes = numOfBytes - BytesToBeCopied;
a2940b63 4088 if (numOfBytes) {
093abf11 4089 if (numOfBytes > Adapter->uiSectorSize)
f8942e07
SH
4090 BytesToBeCopied = Adapter->uiSectorSize;
4091 else
4092 BytesToBeCopied = numOfBytes;
4093 }
093abf11
KM
4094 } while (numOfBytes > 0);
4095
082e889b 4096 kfree(pBuff);
093abf11
KM
4097 Adapter->bHeaderChangeAllowed = FALSE;
4098
f8942e07
SH
4099 return Status;
4100}
4101
4102/**
4103SaveHeaderIfPresent :- 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
4108Return value :-
25985edc 4109 Success :- On success return STATUS_SUCCESS
f8942e07
SH
4110 Faillure :- Return negative error code
4111
4112**/
4113
2979460d 4114INT SaveHeaderIfPresent(struct bcm_mini_adapter *Adapter, PUCHAR pBuff, UINT uiOffset)
f8942e07 4115{
093abf11
KM
4116 UINT offsetToProtect = 0, HeaderSizeToProtect = 0;
4117 BOOLEAN bHasHeader = FALSE;
4118 PUCHAR pTempBuff = NULL;
f8942e07
SH
4119 UINT uiSectAlignAddr = 0;
4120 UINT sig = 0;
4121
25985edc 4122 //making the offset sector aligned
f8942e07
SH
4123 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4124
093abf11
KM
4125 if ((uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD2) - Adapter->uiSectorSize) ||
4126 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD1) - Adapter->uiSectorSize) ||
a2940b63 4127 (uiSectAlignAddr == BcmGetSectionValEndOffset(Adapter, DSD0) - Adapter->uiSectorSize)) {
093abf11 4128 // offset from the sector boundary having the header map
f8942e07
SH
4129 offsetToProtect = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader % Adapter->uiSectorSize;
4130 HeaderSizeToProtect = sizeof(DSD_HEADER);
093abf11 4131 bHasHeader = TRUE;
f8942e07
SH
4132 }
4133
093abf11 4134 if (uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE1) ||
a2940b63 4135 uiSectAlignAddr == BcmGetSectionValStartOffset(Adapter, ISO_IMAGE2)) {
f8942e07
SH
4136 offsetToProtect = 0;
4137 HeaderSizeToProtect = sizeof(ISO_HEADER);
4138 bHasHeader = TRUE;
4139 }
093abf11 4140 // If Header is present overwrite passed buffer with this
a2940b63 4141 if (bHasHeader && (Adapter->bHeaderChangeAllowed == FALSE)) {
f8942e07 4142 pTempBuff = (PUCHAR)kzalloc(HeaderSizeToProtect, GFP_KERNEL);
a2940b63 4143 if (pTempBuff == NULL) {
093abf11 4144 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed");
f8942e07
SH
4145 return -ENOMEM;
4146 }
093abf11
KM
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);
f8942e07 4150 //Replace Buffer content with Header
093abf11 4151 memcpy(pBuff + offsetToProtect, pTempBuff, HeaderSizeToProtect);
f8942e07 4152
082e889b 4153 kfree(pTempBuff);
f8942e07 4154 }
a2940b63 4155 if (bHasHeader && Adapter->bSigCorrupted) {
093abf11 4156 sig = *((PUINT)(pBuff + offsetToProtect + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImageMagicNumber)));
f8942e07 4157 sig = ntohl(sig);
a2940b63 4158 if ((sig & 0xFF000000) != CORRUPTED_PATTERN) {
093abf11 4159 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Desired pattern is not at sig offset. Hence won't restore");
f8942e07
SH
4160 Adapter->bSigCorrupted = FALSE;
4161 return STATUS_SUCCESS;
4162 }
093abf11
KM
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");
f8942e07
SH
4166 Adapter->bSigCorrupted = FALSE;
4167 }
4168
093abf11 4169 return STATUS_SUCCESS;
f8942e07 4170}
f8942e07 4171
f8942e07
SH
4172/**
4173BcmDoChipSelect : This will selcet the appropriate chip for writing.
4174@Adapater :- Bcm Driver Private Data Structure
4175
4176OutPut:-
25985edc 4177 Select the Appropriate chip and retrn status Success
f8942e07 4178**/
2979460d 4179static INT BcmDoChipSelect(struct bcm_mini_adapter *Adapter, UINT offset)
f8942e07
SH
4180{
4181 UINT FlashConfig = 0;
4182 INT ChipNum = 0;
4183 UINT GPIOConfig = 0;
4184 UINT PartNum = 0;
4185
093abf11 4186 ChipNum = offset / FLASH_PART_SIZE;
f8942e07
SH
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 /*
093abf11
KM
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.
f8942e07
SH
4201 */
4202
093abf11
KM
4203 if (Adapter->SelectedChip == ChipNum)
4204 return STATUS_SUCCESS;
f8942e07 4205
093abf11
KM
4206 // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Selected Chip :%x", ChipNum);
4207 Adapter->SelectedChip = ChipNum;
f8942e07 4208
093abf11 4209 // bit[13..12] will select the appropriate chip
41c7b7c0
KM
4210 rdmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
4211 rdmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
f8942e07 4212 {
a2940b63
KM
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;
f8942e07
SH
4229 }
4230 }
4231 /* In case the bits already written in the FLASH_CONFIG_REG is same as what the user desired,
093abf11
KM
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.
f8942e07 4236 */
093abf11 4237 if (PartNum == ((FlashConfig >> CHIP_SELECT_BIT12) & 0x3))
f8942e07
SH
4238 return STATUS_SUCCESS;
4239
093abf11 4240 // clearing the bit[13..12]
f8942e07 4241 FlashConfig &= 0xFFFFCFFF;
093abf11 4242 FlashConfig = (FlashConfig | (PartNum<<CHIP_SELECT_BIT12)); // 00
f8942e07 4243
093abf11 4244 wrmalt(Adapter, FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4);
f8942e07
SH
4245 udelay(100);
4246
093abf11 4247 wrmalt(Adapter, FLASH_CONFIG_REG, &FlashConfig, 4);
f8942e07
SH
4248 udelay(100);
4249
4250 return STATUS_SUCCESS;
f8942e07 4251}
093abf11 4252
2979460d 4253INT ReadDSDSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
f8942e07 4254{
093abf11
KM
4255 UINT uiDSDsig = 0;
4256 //UINT sigoffsetInMap = 0;
4257 //DSD_HEADER dsdHeader = {0};
f8942e07
SH
4258
4259
093abf11 4260 //sigoffsetInMap =(PUCHAR)&(dsdHeader.DSDImageMagicNumber) -(PUCHAR)&dsdHeader;
f8942e07 4261
a2940b63 4262 if (dsd != DSD0 && dsd != DSD1 && dsd != DSD2) {
093abf11
KM
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);
f8942e07 4271
093abf11
KM
4272 uiDSDsig = ntohl(uiDSDsig);
4273 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD SIG :%x", uiDSDsig);
f8942e07 4274
093abf11 4275 return uiDSDsig;
f8942e07 4276}
093abf11 4277
2979460d 4278INT ReadDSDPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL dsd)
f8942e07 4279{
093abf11 4280 // UINT priOffsetInMap = 0 ;
44a17eff 4281 unsigned int uiDSDPri = STATUS_FAILURE;
093abf11
KM
4282 // DSD_HEADER dsdHeader = {0};
4283 // priOffsetInMap = (PUCHAR)&(dsdHeader.DSDImagePriority) -(PUCHAR)&dsdHeader;
a2940b63
KM
4284 if (IsSectionWritable(Adapter, dsd)) {
4285 if (ReadDSDSignature(Adapter, dsd) == DSD_IMAGE_MAGIC_NUMBER) {
f8942e07 4286 BcmFlash2xBulkRead(Adapter,
093abf11
KM
4287 &uiDSDPri,
4288 dsd,
4289 Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + FIELD_OFFSET_IN_HEADER(PDSD_HEADER, DSDImagePriority),
4290 4);
f8942e07
SH
4291
4292 uiDSDPri = ntohl(uiDSDPri);
093abf11 4293 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSD<%x> Priority :%x", dsd, uiDSDPri);
f8942e07
SH
4294 }
4295 }
093abf11 4296
f8942e07
SH
4297 return uiDSDPri;
4298}
093abf11 4299
2979460d 4300FLASH2X_SECTION_VAL getHighestPriDSD(struct bcm_mini_adapter *Adapter)
f8942e07
SH
4301{
4302 INT DSDHighestPri = STATUS_FAILURE;
093abf11
KM
4303 INT DsdPri = 0;
4304 FLASH2X_SECTION_VAL HighestPriDSD = 0;
f8942e07 4305
a2940b63 4306 if (IsSectionWritable(Adapter, DSD2)) {
093abf11
KM
4307 DSDHighestPri = ReadDSDPriority(Adapter, DSD2);
4308 HighestPriDSD = DSD2;
f8942e07 4309 }
093abf11 4310
a2940b63 4311 if (IsSectionWritable(Adapter, DSD1)) {
093abf11 4312 DsdPri = ReadDSDPriority(Adapter, DSD1);
a2940b63 4313 if (DSDHighestPri < DsdPri) {
093abf11 4314 DSDHighestPri = DsdPri;
f8942e07 4315 HighestPriDSD = DSD1;
093abf11 4316 }
f8942e07 4317 }
093abf11 4318
a2940b63 4319 if (IsSectionWritable(Adapter, DSD0)) {
093abf11 4320 DsdPri = ReadDSDPriority(Adapter, DSD0);
a2940b63 4321 if (DSDHighestPri < DsdPri) {
093abf11 4322 DSDHighestPri = DsdPri;
f8942e07 4323 HighestPriDSD = DSD0;
093abf11 4324 }
f8942e07 4325 }
093abf11
KM
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;
f8942e07
SH
4330}
4331
2979460d 4332INT ReadISOSignature(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
f8942e07 4333{
093abf11
KM
4334 UINT uiISOsig = 0;
4335 //UINT sigoffsetInMap = 0;
4336 //ISO_HEADER ISOHeader = {0};
4337 //sigoffsetInMap =(PUCHAR)&(ISOHeader.ISOImageMagicNumber) -(PUCHAR)&ISOHeader;
f8942e07 4338
a2940b63 4339 if (iso != ISO_IMAGE1 && iso != ISO_IMAGE2) {
093abf11
KM
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);
f8942e07 4348
093abf11
KM
4349 uiISOsig = ntohl(uiISOsig);
4350 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO SIG :%x", uiISOsig);
f8942e07 4351
093abf11 4352 return uiISOsig;
f8942e07 4353}
093abf11 4354
2979460d 4355INT ReadISOPriority(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL iso)
f8942e07 4356{
44a17eff 4357 unsigned int ISOPri = STATUS_FAILURE;
a2940b63
KM
4358 if (IsSectionWritable(Adapter, iso)) {
4359 if (ReadISOSignature(Adapter, iso) == ISO_IMAGE_MAGIC_NUMBER) {
f8942e07 4360 BcmFlash2xBulkRead(Adapter,
093abf11
KM
4361 &ISOPri,
4362 iso,
4363 0 + FIELD_OFFSET_IN_HEADER(PISO_HEADER, ISOImagePriority),
4364 4);
f8942e07
SH
4365
4366 ISOPri = ntohl(ISOPri);
093abf11 4367 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISO<%x> Priority :%x", iso, ISOPri);
f8942e07
SH
4368 }
4369 }
093abf11 4370
f8942e07
SH
4371 return ISOPri;
4372}
093abf11 4373
2979460d 4374FLASH2X_SECTION_VAL getHighestPriISO(struct bcm_mini_adapter *Adapter)
f8942e07
SH
4375{
4376 INT ISOHighestPri = STATUS_FAILURE;
093abf11
KM
4377 INT ISOPri = 0;
4378 FLASH2X_SECTION_VAL HighestPriISO = NO_SECTION_VAL;
f8942e07 4379
a2940b63 4380 if (IsSectionWritable(Adapter, ISO_IMAGE2)) {
093abf11
KM
4381 ISOHighestPri = ReadISOPriority(Adapter, ISO_IMAGE2);
4382 HighestPriISO = ISO_IMAGE2;
f8942e07 4383 }
093abf11 4384
a2940b63 4385 if (IsSectionWritable(Adapter, ISO_IMAGE1)) {
093abf11 4386 ISOPri = ReadISOPriority(Adapter, ISO_IMAGE1);
a2940b63 4387 if (ISOHighestPri < ISOPri) {
093abf11 4388 ISOHighestPri = ISOPri;
f8942e07 4389 HighestPriISO = ISO_IMAGE1;
093abf11 4390 }
f8942e07 4391 }
093abf11
KM
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;
f8942e07 4396}
093abf11 4397
2979460d 4398INT WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
093abf11
KM
4399 PUINT pBuff,
4400 FLASH2X_SECTION_VAL eFlash2xSectionVal,
4401 UINT uiOffset,
4402 UINT uiNumBytes)
f8942e07 4403{
093abf11
KM
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
f8942e07 4409 UINT uiStartOffset = 0;
093abf11 4410 // Adding section start address
f8942e07
SH
4411 INT Status = STATUS_SUCCESS;
4412 PUCHAR pcBuff = (PUCHAR)pBuff;
4413
a2940b63 4414 if (uiNumBytes % Adapter->ulFlashWriteSize) {
093abf11 4415 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Writing without Sector Erase for non-FlashWriteSize number of bytes 0x%x\n", uiNumBytes);
f8942e07
SH
4416 return STATUS_FAILURE;
4417 }
4418
093abf11 4419 uiStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
f8942e07 4420
093abf11 4421 if (IsSectionExistInVendorInfo(Adapter, eFlash2xSectionVal))
f8942e07 4422 return vendorextnWriteSectionWithoutErase(Adapter, pcBuff, eFlash2xSectionVal, uiOffset, uiNumBytes);
f8942e07
SH
4423
4424 uiOffset = uiOffset + uiStartOffset;
4425
093abf11
KM
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));
f8942e07 4432
093abf11
KM
4433 Adapter->SelectedChip = RESET_CHIP_SELECT;
4434 BcmDoChipSelect(Adapter, uiOffset);
4435 uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
f8942e07 4436
a2940b63 4437 for (i = 0 ; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
093abf11
KM
4438 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
4439 Status = flashByteWrite(Adapter, uiPartOffset, pcBuff);
4440 else
4441 Status = flashWrite(Adapter, uiPartOffset, pcBuff);
f8942e07 4442
093abf11
KM
4443 if (Status != STATUS_SUCCESS)
4444 break;
f8942e07 4445
093abf11
KM
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
f8942e07
SH
4452
4453 return Status;
4454}
4455
2979460d 4456BOOLEAN IsSectionExistInFlash(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL section)
f8942e07 4457{
093abf11 4458 BOOLEAN SectionPresent = FALSE;
f8942e07 4459
a2940b63
KM
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;
f8942e07 4506 }
093abf11
KM
4507
4508 return SectionPresent;
f8942e07 4509}
093abf11 4510
2979460d 4511INT IsSectionWritable(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL Section)
f8942e07 4512{
093abf11
KM
4513 INT offset = STATUS_FAILURE;
4514 INT Status = FALSE;
f8942e07 4515
a2940b63 4516 if (IsSectionExistInFlash(Adapter, Section) == FALSE) {
093abf11
KM
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);
a2940b63 4522 if (offset == INVALID_OFFSET) {
093abf11
KM
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))
093abf11 4528 return !(Adapter->psFlash2xVendorInfo->VendorSection[Section].AccessFlags & FLASH2X_SECTION_RO);
f8942e07 4529
093abf11
KM
4530 Status = IsOffsetWritable(Adapter, offset);
4531 return Status;
f8942e07
SH
4532}
4533
2979460d 4534static INT CorruptDSDSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
f8942e07 4535{
44a17eff 4536 PUCHAR pBuff = NULL;
f8942e07
SH
4537 UINT sig = 0;
4538 UINT uiOffset = 0;
4539 UINT BlockStatus = 0;
4540 UINT uiSectAlignAddr = 0;
4541
4542 Adapter->bSigCorrupted = FALSE;
a2940b63
KM
4543 if (Adapter->bAllDSDWriteAllow == FALSE) {
4544 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
093abf11 4545 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
f8942e07
SH
4546 return SECTOR_IS_NOT_WRITABLE;
4547 }
4548 }
4549
4550 pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
a2940b63 4551 if (pBuff == NULL) {
093abf11
KM
4552 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4553 return -ENOMEM;
f8942e07
SH
4554 }
4555
4556 uiOffset = Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER);
093abf11 4557 uiOffset -= MAX_RW_SIZE;
f8942e07 4558
093abf11 4559 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
f8942e07 4560
093abf11
KM
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.
f8942e07
SH
4565 *(pBuff + 12) = 0;
4566
a2940b63 4567 if (sig == DSD_IMAGE_MAGIC_NUMBER) {
f8942e07 4568 Adapter->bSigCorrupted = TRUE;
a2940b63 4569 if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT) {
093abf11
KM
4570 uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1);
4571 BlockStatus = BcmFlashUnProtectBlock(Adapter, uiSectAlignAddr, Adapter->uiSectorSize);
f8942e07 4572
093abf11
KM
4573 WriteToFlashWithoutSectorErase(Adapter, (PUINT)(pBuff + 12), eFlash2xSectionVal,
4574 (uiOffset + 12), BYTE_WRITE_SUPPORT);
a2940b63 4575 if (BlockStatus) {
093abf11 4576 BcmRestoreBlockProtectStatus(Adapter, BlockStatus);
f8942e07
SH
4577 BlockStatus = 0;
4578 }
a2940b63 4579 } else {
093abf11
KM
4580 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4581 uiOffset, MAX_RW_SIZE);
f8942e07 4582 }
a2940b63 4583 } else {
093abf11 4584 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
082e889b 4585 kfree(pBuff);
093abf11 4586
f8942e07
SH
4587 return STATUS_FAILURE;
4588 }
4589
082e889b 4590 kfree(pBuff);
093abf11
KM
4591 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Corrupted the signature");
4592
4593 return STATUS_SUCCESS;
f8942e07
SH
4594}
4595
2979460d 4596static INT CorruptISOSig(struct bcm_mini_adapter *Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal)
f8942e07 4597{
44a17eff 4598 PUCHAR pBuff = NULL;
f8942e07
SH
4599 UINT sig = 0;
4600 UINT uiOffset = 0;
4601
4602 Adapter->bSigCorrupted = FALSE;
4603
a2940b63 4604 if (IsSectionWritable(Adapter, eFlash2xSectionVal) != TRUE) {
093abf11 4605 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section is not Writable...Hence can't Corrupt signature");
f8942e07
SH
4606 return SECTOR_IS_NOT_WRITABLE;
4607 }
4608
4609 pBuff = (PUCHAR)kzalloc(MAX_RW_SIZE, GFP_KERNEL);
a2940b63 4610 if (pBuff == NULL) {
093abf11
KM
4611 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Can't allocate memorey");
4612 return -ENOMEM;
f8942e07
SH
4613 }
4614
4615 uiOffset = 0;
4616
093abf11 4617 BcmFlash2xBulkRead(Adapter, (PUINT)pBuff, eFlash2xSectionVal, uiOffset, MAX_RW_SIZE);
f8942e07
SH
4618
4619 sig = *((PUINT)pBuff);
093abf11 4620 sig = ntohl(sig);
f8942e07 4621
093abf11 4622 // corrupt signature
f8942e07
SH
4623 *pBuff = 0;
4624
a2940b63 4625 if (sig == ISO_IMAGE_MAGIC_NUMBER) {
f8942e07 4626 Adapter->bSigCorrupted = TRUE;
093abf11
KM
4627 WriteToFlashWithoutSectorErase(Adapter, (PUINT)pBuff, eFlash2xSectionVal,
4628 uiOffset, Adapter->ulFlashWriteSize);
a2940b63 4629 } else {
093abf11 4630 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "BCM Signature is not present in header");
082e889b 4631 kfree(pBuff);
093abf11 4632
f8942e07
SH
4633 return STATUS_FAILURE;
4634 }
4635
093abf11
KM
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);
f8942e07 4638
082e889b 4639 kfree(pBuff);
093abf11 4640 return STATUS_SUCCESS;
f8942e07
SH
4641}
4642
2979460d 4643BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter)
f8942e07 4644{
093abf11 4645 if (Adapter->psFlash2xCSInfo->IsCDLessDeviceBootSig == NON_CDLESS_DEVICE_BOOT_SIG)
f8942e07
SH
4646 return TRUE;
4647 else
093abf11 4648 return FALSE;
f8942e07 4649}
This page took 0.459923 seconds and 5 git commands to generate.