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