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