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