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