xref: /illumos-gate/usr/src/uts/common/io/bnx/570x/driver/common/lmdev/bnx_hw_nvram.c (revision eef4f27b270242808b43b4b23bd161df52839361)
1 /*
2  * Copyright 2014-2017 Cavium, Inc.
3  * The contents of this file are subject to the terms of the Common Development
4  * and Distribution License, v.1,  (the "License").
5  *
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the License at available
9  * at http://opensource.org/licenses/CDDL-1.0
10  *
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14 
15 #include "lm5706.h"
16 
17 
18 /*******************************************************************************
19  * Constants.
20  ******************************************************************************/
21 
22 /* Buffered flash (Atmel: AT45DB011B) specific information */
23 #define SEEPROM_SHIFT_BITS                      2
24 #define SEEPROM_PHY_PAGE_SIZE                   (1 << SEEPROM_SHIFT_BITS)
25 #define SEEPROM_BYTE_ADDR_MASK                  (SEEPROM_PHY_PAGE_SIZE-1)
26 #define SEEPROM_PAGE_SIZE                       4
27 #define SEEPROM_TOTAL_SIZE                      65536
28 
29 #define BUFFERED_FLASH_SHIFT_BITS               9
30 #define BUFFERED_FLASH_PHY_PAGE_SIZE            (1 << BUFFERED_FLASH_SHIFT_BITS)
31 #define BUFFERED_FLASH_BYTE_ADDR_MASK           (BUFFERED_FLASH_PHY_PAGE_SIZE-1)
32 #define BUFFERED_FLASH_PAGE_SIZE                264
33 #define BUFFERED_FLASH_TOTAL_SIZE               0x21000
34 
35 #define SAIFUN_FLASH_SHIFT_BITS                 8
36 #define SAIFUN_FLASH_PHY_PAGE_SIZE              (1 << SAIFUN_FLASH_SHIFT_BITS)
37 #define SAIFUN_FLASH_BYTE_ADDR_MASK             (SAIFUN_FLASH_PHY_PAGE_SIZE-1)
38 #define SAIFUN_FLASH_PAGE_SIZE                  256
39 #define SAIFUN_FLASH_BASE_TOTAL_SIZE            65536
40 
41 #define ST_MICRO_FLASH_SHIFT_BITS               8
42 #define ST_MICRO_FLASH_PHY_PAGE_SIZE            (1 << ST_MICRO_FLASH_SHIFT_BITS)
43 #define ST_MICRO_FLASH_BYTE_ADDR_MASK           (ST_MICRO_FLASH_PHY_PAGE_SIZE-1)
44 #define ST_MICRO_FLASH_PAGE_SIZE                256
45 #define ST_MICRO_FLASH_BASE_TOTAL_SIZE          65536
46 #define ST_MICRO_FLASH_1MBIT                    0x20000
47 
48 /* NVRAM flags for nvram_write_dword and nvram_read_dword. */
49 #define NVRAM_FLAG_NONE                         0x00
50 #define NVRAM_FLAG_SET_FIRST_CMD_BIT            0x01
51 #define NVRAM_FLAG_SET_LAST_CMD_BIT             0x02
52 #define NVRAM_FLAG_BUFFERED_FLASH               0x04
53 
54 #define NVRAM_TIMEOUT_COUNT                     30000
55 
56 
57 #define FLASH_STRAP_MASK                        (NVM_CFG1_FLASH_MODE   | \
58                                                  NVM_CFG1_BUFFER_MODE  | \
59                                                  NVM_CFG1_PROTECT_MODE | \
60                                                  NVM_CFG1_FLASH_SIZE)
61 #define FLASH_BACKUP_STRAP_MASK                 (0xf << 26)
62 
63 
64 typedef struct _new_nvm_cfg_t
65 {
66     /* Strapping to indicate the flash type (original | backup) */
67     u32_t strapping;
68     /* New configuration values */
69     u32_t config1;
70     u32_t config2;
71     u32_t config3;
72     u32_t write1;
73     u32_t buffered;
74     u32_t shift_bits;
75     u32_t page_size;
76     u32_t addr_mask;
77     u32_t total_size;
78     char *name;
79 } new_nvm_cfg_t;
80 
81 /* This table is indexed by the strap values */
82 static const new_nvm_cfg_t cfg_table[] =
83 {
84     /* Slow EEPROM */
85     {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
86      1, SEEPROM_SHIFT_BITS, SEEPROM_PAGE_SIZE,
87      SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
88      "EEPROM - slow"},
89     /* Expansion entry 0001 */
90     {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
91      0, SAIFUN_FLASH_SHIFT_BITS, SAIFUN_FLASH_PAGE_SIZE,
92      SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
93      "Entry 0001"},
94     /* Saifun SA25F010 (non-buffered flash) */
95     {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,  /* strap, cfg1, & write1 need updates */
96      0, SAIFUN_FLASH_SHIFT_BITS, SAIFUN_FLASH_PAGE_SIZE,
97      SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
98      "Non-buffered flash (128kB)"},
99     /* Saifun SA25F020 (non-buffered flash) */
100     {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,  /* strap, cfg1, & write1 need updates */
101      0, SAIFUN_FLASH_SHIFT_BITS, SAIFUN_FLASH_PAGE_SIZE,
102      SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
103      "Non-buffered flash (256kB)"},
104     /* Expansion entry 0100 */
105     {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
106      0, SAIFUN_FLASH_SHIFT_BITS, SAIFUN_FLASH_PAGE_SIZE,
107      SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
108      "Entry 0100"},
109     /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
110     {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
111      0, ST_MICRO_FLASH_SHIFT_BITS, ST_MICRO_FLASH_PAGE_SIZE,
112      ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
113      "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
114     /* Entry 0110: ST M45PE20 (non-buffered flash)*/
115     {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
116      0, ST_MICRO_FLASH_SHIFT_BITS, ST_MICRO_FLASH_PAGE_SIZE,
117      ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
118      "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
119     /* Saifun SA25F005 (non-buffered flash) */
120     {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,  /* strap, cfg1, & write1 need updates */
121      0, SAIFUN_FLASH_SHIFT_BITS, SAIFUN_FLASH_PAGE_SIZE,
122      SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
123      "Non-buffered flash (64kB)"},
124     /* Fast EEPROM */
125     {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
126      1, SEEPROM_SHIFT_BITS, SEEPROM_PAGE_SIZE,
127      SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
128      "EEPROM - fast"},
129     /* Expansion entry 1001 */
130     {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
131      0, SAIFUN_FLASH_SHIFT_BITS, SAIFUN_FLASH_PAGE_SIZE,
132      SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
133      "Entry 1001"},
134     /* Expansion entry 1010 */
135     {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
136      0, SAIFUN_FLASH_SHIFT_BITS, SAIFUN_FLASH_PAGE_SIZE,
137      SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
138      "Entry 1010"},
139     /* ATMEL AT45DB011B (buffered flash) */
140     {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
141      1, BUFFERED_FLASH_SHIFT_BITS, BUFFERED_FLASH_PAGE_SIZE,
142      BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
143      "Buffered flash (128kB)"},
144     /* Expansion entry 1100 */
145     {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
146      0, SAIFUN_FLASH_SHIFT_BITS, SAIFUN_FLASH_PAGE_SIZE,
147      SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
148      "Entry 1100"},
149     /* Expansion entry 1101 */
150     {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
151      0, SAIFUN_FLASH_SHIFT_BITS, SAIFUN_FLASH_PAGE_SIZE,
152      SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
153      "Entry 1101"},
154     /* Ateml Expansion entry 1110 */
155     {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
156      1, BUFFERED_FLASH_SHIFT_BITS, BUFFERED_FLASH_PAGE_SIZE,
157      BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
158      "Entry 1110 (Atmel)"},
159     /* ATMEL AT45DB021B (buffered flash) */
160     {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
161      1, BUFFERED_FLASH_SHIFT_BITS, BUFFERED_FLASH_PAGE_SIZE,
162      BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
163      "Buffered flash (256kB)"},
164 };
165 
166 /*******************************************************************************
167  * Description:
168  *
169  * Return:
170  ******************************************************************************/
171 STATIC lm_status_t
acquire_nvram_lock(lm_device_t * pdev)172 acquire_nvram_lock(
173     lm_device_t *pdev)
174 {
175     lm_status_t lm_status;
176     u32_t j, cnt;
177     u32_t val;
178 
179     /* Adjust timeout for emulation/FPGA */
180     cnt = NVRAM_TIMEOUT_COUNT;
181     if (CHIP_REV(pdev) == CHIP_REV_FPGA) cnt *= 10;
182     else if (CHIP_REV(pdev) == CHIP_REV_IKOS) cnt *= 100;
183 
184     val = 0;
185 
186     /* Request access to the flash interface. */
187     REG_WR(pdev, nvm.nvm_sw_arb, NVM_SW_ARB_ARB_REQ_SET2);
188 
189     for(j = 0; j < cnt*10; j++)
190     {
191         REG_RD(pdev, nvm.nvm_sw_arb, &val);
192         if(val & NVM_SW_ARB_ARB_ARB2)
193         {
194             break;
195         }
196         mm_wait(pdev, 5);
197     }
198 
199     if(val & NVM_SW_ARB_ARB_ARB2)
200     {
201         lm_status = LM_STATUS_SUCCESS;
202     }
203     else
204     {
205         DbgBreakMsg("Cannot get access to nvram interface.\n");
206 
207         lm_status = LM_STATUS_BUSY;
208     }
209     return lm_status;
210 } /* acquire_nvram_lock */
211 
212 
213 
214 /*******************************************************************************
215  * Description:
216  *
217  * Return:
218  ******************************************************************************/
219 STATIC void
release_nvram_lock(lm_device_t * pdev)220 release_nvram_lock(
221     lm_device_t *pdev)
222 {
223     u32_t j, cnt;
224     u32_t val;
225 
226     /* Relinquish nvram interface. */
227     REG_WR(pdev, nvm.nvm_sw_arb, NVM_SW_ARB_ARB_REQ_CLR2);
228 
229     /* Adjust timeout for emulation/FPGA */
230     cnt = NVRAM_TIMEOUT_COUNT;
231     if (CHIP_REV(pdev) == CHIP_REV_FPGA) cnt *= 10;
232     else if (CHIP_REV(pdev) == CHIP_REV_IKOS) cnt *= 100;
233 
234     val = 0;
235 
236     for(j = 0; j < cnt; j++)
237     {
238         REG_RD(pdev, nvm.nvm_sw_arb, &val);
239         if(!(val & NVM_SW_ARB_ARB_ARB2))
240         {
241             break;
242         }
243 
244         mm_wait(pdev, 5);
245     }
246 
247     DbgBreakIf(val & NVM_SW_ARB_ARB_ARB2);
248 } /* release_nvram_lock */
249 
250 
251 
252 /*******************************************************************************
253  * Description:
254  *
255  * Return:
256  *
257  ******************************************************************************/
258 STATIC lm_status_t
enable_nvram_write(lm_device_t * pdev)259 enable_nvram_write(
260     lm_device_t *pdev)
261 {
262     u32_t val, j, cnt;
263     lm_status_t lm_status;
264 
265     REG_RD(pdev, misc.misc_cfg, &val);
266     REG_WR(pdev, misc.misc_cfg, val | MISC_CFG_NVM_WR_EN_PCI);
267 
268     lm_status = LM_STATUS_SUCCESS;
269 
270     if (!pdev->hw_info.flash_spec.buffered)
271     {
272         REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_DONE);
273         REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_WREN  |
274                                       NVM_COMMAND_DOIT);
275 
276         /* Adjust timeout for emulation/FPGA */
277         cnt = NVRAM_TIMEOUT_COUNT;
278         if (CHIP_REV(pdev) == CHIP_REV_FPGA) cnt *= 10;
279         else if (CHIP_REV(pdev) == CHIP_REV_IKOS) cnt *= 100;
280 
281         lm_status = LM_STATUS_BUSY;
282 
283         for(j = 0; j < cnt; j++)
284         {
285             mm_wait(pdev, 5);
286 
287             REG_RD(pdev, nvm.nvm_command, &val);
288             if(val & NVM_COMMAND_DONE)
289             {
290                 lm_status = LM_STATUS_SUCCESS;
291                 break;
292             }
293         }
294     }
295 
296     return lm_status;
297 } /* enable_nvram_write */
298 
299 
300 
301 /*******************************************************************************
302  * Description:
303  *
304  * Return:
305  *
306  ******************************************************************************/
307 STATIC lm_status_t
disable_nvram_write(lm_device_t * pdev)308 disable_nvram_write(
309     lm_device_t *pdev)
310 {
311     lm_status_t lm_status;
312     u32_t val;
313 
314     REG_RD(pdev, misc.misc_cfg, &val);
315     REG_WR(pdev, misc.misc_cfg, val & ~MISC_CFG_NVM_WR_EN);
316     lm_status = LM_STATUS_SUCCESS;
317 
318 #if 0 /* On Saifun and ST parts, WP kicks in at the end of the write.
319          So, no need to have this. */
320     if (!pdev->hw_info.flash_spec.buffered)
321     {
322         /* Restoring protection causes the next read at a wrong location;
323          * leave this out for now. */
324         REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_DONE);
325         REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_WRDI  |
326                                       NVM_COMMAND_DOIT);
327 
328         /* Adjust timeout for emulation/FPGA */
329         cnt = NVRAM_TIMEOUT_COUNT;
330         if (CHIP_REV(pdev) == CHIP_REV_FPGA) cnt *= 10;
331         else if (CHIP_REV(pdev) == CHIP_REV_IKOS) cnt *= 100;
332 
333         lm_status = LM_STATUS_BUSY;
334         for(j = 0; j < cnt; j++)
335         {
336             mm_wait(pdev, 5);
337 
338             REG_RD(pdev, nvm.nvm_command, &val);
339             if(val & NVM_COMMAND_DONE)
340             {
341                 lm_status = LM_STATUS_SUCCESS;
342                 break;
343             }
344         }
345     }
346 #endif
347 
348     return lm_status;
349 } /* disable_nvram_write */
350 
351 
352 
353 /*******************************************************************************
354  * Description:
355  *
356  * Return:
357  ******************************************************************************/
358 STATIC lm_status_t
enable_nvram_access(lm_device_t * pdev)359 enable_nvram_access(
360     lm_device_t *pdev)
361 {
362     u32_t val;
363 
364     REG_RD(pdev, nvm.nvm_access_enable, &val);
365 
366     /* Enable both bits, even on read. */
367     REG_WR(
368         pdev,
369         nvm.nvm_access_enable,
370        val | NVM_ACCESS_ENABLE_EN | NVM_ACCESS_ENABLE_WR_EN);
371 
372     return LM_STATUS_SUCCESS;
373 } /* enable_nvram_access */
374 
375 
376 
377 /*******************************************************************************
378  * Description:
379  *
380  * Return:
381  ******************************************************************************/
382 STATIC lm_status_t
disable_nvram_access(lm_device_t * pdev)383 disable_nvram_access(
384     lm_device_t *pdev)
385 {
386     u32_t val;
387 
388     REG_RD(pdev, nvm.nvm_access_enable, &val);
389 
390     /* Disable both bits, even after read. */
391     REG_WR(
392         pdev,
393         nvm.nvm_access_enable,
394         val & ~(NVM_ACCESS_ENABLE_EN | NVM_ACCESS_ENABLE_WR_EN));
395 
396     return LM_STATUS_SUCCESS;
397 } /* disable_nvram_access */
398 
399 
400 
401 /*******************************************************************************
402  * Description:
403  *
404  * Return:
405  ******************************************************************************/
406 STATIC lm_status_t
nvram_erase_page(lm_device_t * pdev,u32_t offset)407 nvram_erase_page(
408     lm_device_t *pdev,
409     u32_t offset)
410 {
411     lm_status_t lm_status;
412     u32_t cmd_flags;
413     u32_t val;
414     u32_t j, cnt;
415 
416     if (pdev->hw_info.flash_spec.buffered)
417     {
418         /* Buffered flash, no erase needed */
419         return LM_STATUS_SUCCESS;
420     }
421 
422     /* Build an erase command */
423     cmd_flags = NVM_COMMAND_ERASE | NVM_COMMAND_WR | NVM_COMMAND_DOIT;
424 
425     /* Need to clear DONE bit separately. */
426     REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_DONE);
427 
428     /* Address of the NVRAM to read from. */
429     REG_WR(pdev, nvm.nvm_addr, offset & NVM_ADDR_NVM_ADDR_VALUE);
430 
431     /* Issue an erase command. */
432     REG_WR(pdev, nvm.nvm_command, cmd_flags);
433 
434     /* Adjust timeout for emulation/FPGA */
435     cnt = NVRAM_TIMEOUT_COUNT;
436     if (CHIP_REV(pdev) == CHIP_REV_FPGA) cnt *= 10;
437     else if (CHIP_REV(pdev) == CHIP_REV_IKOS) cnt *= 100;
438 
439     /* Wait for completion. */
440     lm_status = LM_STATUS_BUSY;
441     for(j = 0; j < cnt; j++)
442     {
443         mm_wait(pdev, 5);
444 
445         REG_RD(pdev, nvm.nvm_command, &val);
446         if(val & NVM_COMMAND_DONE)
447         {
448             lm_status = LM_STATUS_SUCCESS;
449             break;
450         }
451     }
452 
453     return lm_status;
454 
455 } /* nvram_erase_page */
456 
457 
458 
459 /*******************************************************************************
460  * Description:
461  *
462  * Return:
463  ******************************************************************************/
464 STATIC lm_status_t
nvram_read_dword(lm_device_t * pdev,u32_t offset,u32_t * ret_val,u32_t nvram_flags)465 nvram_read_dword(
466     lm_device_t *pdev,
467     u32_t offset,
468     u32_t *ret_val,
469     u32_t nvram_flags)
470 {
471     lm_status_t lm_status;
472     u32_t cmd_flags;
473     u32_t val;
474     u32_t j, cnt;
475 
476     /* Build the command word. */
477     cmd_flags = NVM_COMMAND_DOIT;
478     if(nvram_flags & NVRAM_FLAG_SET_FIRST_CMD_BIT)
479     {
480         cmd_flags |= NVM_COMMAND_FIRST;
481     }
482 
483     if(nvram_flags & NVRAM_FLAG_SET_LAST_CMD_BIT)
484     {
485         cmd_flags |= NVM_COMMAND_LAST;
486     }
487 
488     if ((CHIP_NUM(pdev) == CHIP_NUM_5706) || (CHIP_NUM(pdev) == CHIP_NUM_5708))
489     {
490         /* Calculate an offset of a buffered flash. */
491         if(nvram_flags & NVRAM_FLAG_BUFFERED_FLASH)
492         {
493             offset = ((offset / pdev->hw_info.flash_spec.page_size) <<
494                        pdev->hw_info.flash_spec.shift_bits) +
495                      (offset % pdev->hw_info.flash_spec.page_size);
496         }
497 
498         /* Need to clear DONE bit separately. */
499         REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_DONE);
500     }
501 
502     /* Address of the NVRAM to read from. */
503     if (cmd_flags & NVM_COMMAND_FIRST) {
504         REG_WR(pdev, nvm.nvm_addr, offset & NVM_ADDR_NVM_ADDR_VALUE);
505     }
506 
507     /* Issue a read command. */
508     REG_WR(pdev, nvm.nvm_command, cmd_flags);
509 
510     /* Adjust timeout for emulation/FPGA */
511     cnt = NVRAM_TIMEOUT_COUNT;
512     if (CHIP_REV(pdev) == CHIP_REV_FPGA) cnt *= 10;
513     else if (CHIP_REV(pdev) == CHIP_REV_IKOS) cnt *= 100;
514 
515     /* Wait for completion. */
516     lm_status = LM_STATUS_BUSY;
517     for(j = 0; j < cnt; j++)
518     {
519         mm_wait(pdev, 5);
520 
521         REG_RD(pdev, nvm.nvm_command, &val);
522         if(val & NVM_COMMAND_DONE)
523         {
524             REG_RD(pdev, nvm.nvm_read, &val);
525 
526             /* Change to little endian. */
527             #if defined(LITTLE_ENDIAN)
528             val = ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
529                 ((val & 0xff0000) >> 8) | ((val >> 24) & 0xff);
530             #endif
531 
532             *ret_val = val;
533 
534             lm_status = LM_STATUS_SUCCESS;
535 
536             break;
537         }
538     }
539 
540     return lm_status;
541 } /* nvram_read_dword */
542 
543 
544 
545 /*******************************************************************************
546  * Description:
547  *
548  * Return:
549  ******************************************************************************/
550 STATIC lm_status_t
nvram_write_dword(lm_device_t * pdev,u32_t offset,u32_t val,u32_t nvram_flags)551 nvram_write_dword(
552     lm_device_t *pdev,
553     u32_t offset,
554     u32_t val,
555     u32_t nvram_flags)
556 {
557     lm_status_t lm_status;
558     u32_t cmd_flags;
559     u32_t j, cnt;
560 
561     /* Build the command word. */
562     cmd_flags = NVM_COMMAND_DOIT | NVM_COMMAND_WR;
563     if(nvram_flags & NVRAM_FLAG_SET_FIRST_CMD_BIT)
564     {
565         cmd_flags |= NVM_COMMAND_FIRST;
566     }
567 
568     if(nvram_flags & NVRAM_FLAG_SET_LAST_CMD_BIT)
569     {
570         cmd_flags |= NVM_COMMAND_LAST;
571     }
572     if ((CHIP_NUM(pdev) == CHIP_NUM_5706) || (CHIP_NUM(pdev) == CHIP_NUM_5708))
573     {
574         /* Calculate an offset of a buffered flash. */
575         if(nvram_flags & NVRAM_FLAG_BUFFERED_FLASH)
576         {
577             offset = ((offset / pdev->hw_info.flash_spec.page_size) <<
578                       pdev->hw_info.flash_spec.shift_bits) +
579                      (offset % pdev->hw_info.flash_spec.page_size);
580         }
581 
582         /* Need to clear DONE bit separately. */
583         REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_DONE);
584     }
585 
586     /* Change to little endian. */
587     #if defined(LITTLE_ENDIAN)
588     val = ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
589         ((val & 0xff0000) >> 8) | ((val >> 24) & 0xff);
590     #endif
591 
592     /* Write the data. */
593     REG_WR(pdev, nvm.nvm_write, val);
594 
595     /* Address of the NVRAM to write to. */
596     if (cmd_flags & NVM_COMMAND_FIRST) {
597         REG_WR(pdev, nvm.nvm_addr, offset & NVM_ADDR_NVM_ADDR_VALUE);
598     }
599 
600     /* Issue the write command. */
601     REG_WR(pdev, nvm.nvm_command, cmd_flags);
602 
603     /* Adjust timeout for emulation/FPGA */
604     cnt = NVRAM_TIMEOUT_COUNT;
605     if (CHIP_REV(pdev) == CHIP_REV_FPGA) cnt *= 10;
606     else if (CHIP_REV(pdev) == CHIP_REV_IKOS) cnt *= 100;
607 
608     /* Wait for completion. */
609     lm_status = LM_STATUS_BUSY;
610     for(j = 0; j < cnt; j++)
611     {
612         mm_wait(pdev, 5);
613 
614         REG_RD(pdev, nvm.nvm_command, &val);
615         if(val & NVM_COMMAND_DONE)
616         {
617             lm_status = LM_STATUS_SUCCESS;
618             break;
619         }
620     }
621 
622     return lm_status;
623 } /* nvram_write_dword */
624 
625 
626 
627 /*******************************************************************************
628  * Description:
629  *
630  * Return:
631  ******************************************************************************/
632 STATIC u32_t
find_atmel_size(lm_device_t * pdev)633 find_atmel_size(
634     lm_device_t *pdev)
635 {
636     u32_t orig, val, done=0, size=BUFFERED_FLASH_TOTAL_SIZE;
637 
638     if (CHIP_NUM(pdev) == CHIP_NUM_5709)
639     {
640         REG_RD(pdev, nvm.nvm_cfg4, &val);
641         val &= 0x07;
642         return (1 << val) ;
643     }
644 
645     /* It is assumed that the flash is enabled and locked for exclusive access */
646     REG_RD(pdev, nvm.nvm_cfg3, &orig);
647     REG_WR(pdev, nvm.nvm_cfg3, 0x57848353);
648     REG_WR(pdev, nvm.nvm_read, 0);
649     REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_DONE);
650     REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_DOIT |
651                                   NVM_COMMAND_FIRST |
652                                   NVM_COMMAND_LAST);
653     while (!done)
654     {
655         REG_RD(pdev, nvm.nvm_command, &val);
656         if (val & NVM_COMMAND_DONE)
657         {
658             done = 1;
659         }
660     }
661     REG_RD(pdev, nvm.nvm_read, &val);
662     REG_WR(pdev, nvm.nvm_cfg3, orig);
663     val &= 0x3c;
664     switch (val)
665     {
666         case 0x24:
667             size *= 8;
668             break;
669         case 0x1c:
670             size *= 4;
671             break;
672         case 0x14:
673             size *= 2;
674             break;
675         case 0x0c:
676             size *= 1;
677             break;
678         default:
679             size *= 0;
680             break;
681     }
682     return size;
683 }
684 
685 
686 /*******************************************************************************
687  * Description:
688  *
689  * Return:
690  ******************************************************************************/
691 STATIC u32_t
find_stm_size(lm_device_t * pdev)692 find_stm_size(
693     lm_device_t *pdev)
694 {
695     u32_t idx, val, result, bit;
696 
697     if (CHIP_NUM(pdev) == CHIP_NUM_5709)
698     {
699         REG_RD(pdev, nvm.nvm_cfg4, &val);
700         val &= 0x07;
701         return (1 << val) ;
702     }
703 
704     /* It is assumed that the flash is enabled and locked for exclusive access */
705     /* Set CS, SO, SCLK as output, SI as input */
706     REG_WR(pdev, nvm.nvm_addr, NVM_ADDR_NVM_ADDR_VALUE_EECLK_TE |
707                                NVM_ADDR_NVM_ADDR_VALUE_EEDATA_TE |
708                                NVM_ADDR_NVM_ADDR_VALUE_SI_TE
709                                );
710     /* Set initial data CS=1, SO=0, SCLK=0, SI=n/a */
711     REG_WR(pdev, nvm.nvm_write, NVM_WRITE_NVM_WRITE_VALUE_EECLK_TE |
712                                 NVM_WRITE_NVM_WRITE_VALUE_EEDATA_TE |
713                                 NVM_WRITE_NVM_WRITE_VALUE_CS_B_TE
714                                 );
715     /* Enable bit-bang mode */
716     REG_RD(pdev, nvm.nvm_cfg1, &val);
717     REG_WR(pdev, nvm.nvm_cfg1, val | NVM_CFG1_BITBANG_MODE);
718     mm_wait(pdev, 1);
719 
720     /* Bit-bang the command */
721 
722     val = 0xf9;
723 
724     REG_WR(pdev, nvm.nvm_write, 0);
725     mm_wait(pdev, 1);
726     for (idx=0; idx < 8; idx++)
727     {
728         bit = ((val >> idx) & 0x1) << 4;
729         REG_WR(pdev, nvm.nvm_write, bit);
730         mm_wait(pdev, 1);
731         REG_WR(pdev, nvm.nvm_write, NVM_WRITE_NVM_WRITE_VALUE_SCLK_TE | bit);
732         mm_wait(pdev, 1);
733     }
734     REG_WR(pdev, nvm.nvm_write, 0);
735     mm_wait(pdev, 1);
736 
737     /* Bit-bang to read ID, 1st byte: manuf ID;
738      * 2nd byte: memory type; 3rd byte: memory capacity */
739     result = 0;
740     for (idx = 0; idx < 24; idx++)
741     {
742         REG_RD(pdev, nvm.nvm_read, &val);
743         bit = (val & NVM_WRITE_NVM_WRITE_VALUE_SI_TE) >> 5;
744         result = (result << 1) | bit;
745 
746         REG_WR(pdev, nvm.nvm_write, NVM_WRITE_NVM_WRITE_VALUE_SCLK_TE);
747         mm_wait(pdev, 1);
748         REG_WR(pdev, nvm.nvm_write, 0);
749         mm_wait(pdev, 1);
750     }
751     REG_WR(pdev, nvm.nvm_write, NVM_WRITE_NVM_WRITE_VALUE_CS_B_TE);
752     mm_wait(pdev, 1);
753 
754     val = ST_MICRO_FLASH_1MBIT;
755     switch (result)
756     {
757         case 0x00204014:
758             val *= 8;
759             break;
760         case 0x00204013:
761             val *= 4;
762             break;
763         case 0x00204012:
764             val *= 2;
765             break;
766         case 0x00204011:
767             val *= 1;
768             break;
769         default:
770             val *= 0;
771             break;
772     }
773 
774     /* Get out of bit-bang mode */
775     REG_RD(pdev, nvm.nvm_cfg1, &idx);
776     REG_WR(pdev, nvm.nvm_cfg1, idx & ~NVM_CFG1_BITBANG_MODE);
777     mm_wait(pdev, 1);
778 
779     return val;
780 }
781 
782 
783 /*******************************************************************************
784  * Description:
785  *
786  * Return:
787  ******************************************************************************/
788 STATIC u32_t
find_nvram_size(lm_device_t * pdev,u32_t table_idx)789 find_nvram_size(
790     lm_device_t *pdev,
791     u32_t table_idx)
792 {
793     lm_status_t lm_status;
794     u32_t size, val;
795 
796     if (CHIP_NUM(pdev) == CHIP_NUM_5709)
797     {
798         REG_RD(pdev, nvm.nvm_cfg4, &val);
799         val &= 0x07;
800         return ((1 << val) * 1024 * 1024 / 8);
801     }
802 
803     /* Request access to the flash interface. */
804     lm_status = acquire_nvram_lock(pdev);
805     if(lm_status != LM_STATUS_SUCCESS) return 0;
806 
807     /* Enable access to flash interface */
808     lm_status = enable_nvram_access(pdev);
809     if(lm_status != LM_STATUS_SUCCESS) return 0;
810 
811     switch (table_idx)
812     {
813         case 11:
814         case 14:
815         case 15:
816             /* ATMEL */
817             size = find_atmel_size(pdev);
818             break;
819         case 5:
820         case 6:
821             size = find_stm_size(pdev);
822             break;
823         case 2:
824         case 3:
825         case 7:
826             /* This one is static */
827             size = cfg_table[table_idx].total_size;
828             break;
829         default:
830             size = 0;
831             break;
832     }
833     /* Disable access to flash interface */
834     (void) disable_nvram_access(pdev);
835     release_nvram_lock(pdev);
836     return size;
837 }
838 
839 
840 /*******************************************************************************
841  * Description:
842  *
843  * Return:
844  ******************************************************************************/
845 void
lm_nvram_init(lm_device_t * pdev,u8_t reset_flash_block)846 lm_nvram_init(
847     lm_device_t *pdev,
848     u8_t reset_flash_block)
849 {
850     u32_t idx, val;
851     lm_status_t lm_status;
852 
853     DbgMessage(pdev, INFORM, "### lm_nvram_init\n");
854 
855     if (CHIP_NUM(pdev) == CHIP_NUM_5709)
856     {
857         REG_RD(pdev, nvm.nvm_cfg4, &val);
858 
859         pdev->hw_info.flash_spec.buffered   = 0;
860         pdev->hw_info.flash_spec.shift_bits = 0;
861         pdev->hw_info.flash_spec.page_size  = SAIFUN_FLASH_PAGE_SIZE;
862         pdev->hw_info.flash_spec.addr_mask  = 0;
863         pdev->hw_info.flash_spec.total_size = (1 << (val & 0x07)) * 1024 * 1024 / 8;
864         return;
865     }
866 
867     idx = lm_nvram_query(pdev, reset_flash_block, FALSE);
868 
869     if (idx == (u32_t)-1)
870     {
871         /* Not necessarily an error, it could mean that the flash block has
872          * been reconfigured.
873          */
874         return;
875     }
876 
877     DbgMessage(pdev, INFORM, cfg_table[idx].name);
878     DbgMessage(pdev, INFORM, " reconfiguring.\n");
879 
880     /* Request access to the flash interface. */
881     lm_status = acquire_nvram_lock(pdev);
882     if(lm_status != LM_STATUS_SUCCESS) return;
883 
884     /* Enable access to flash interface */
885     lm_status = enable_nvram_access(pdev);
886     if(lm_status != LM_STATUS_SUCCESS) return;
887 
888     /* Reconfigure the flash interface */
889     /*     Program the SPI and SEE clocks faster if FPGA or IKOS */
890     val = cfg_table[idx].config1;
891 
892     if(CHIP_REV(pdev) == CHIP_REV_FPGA)
893     {
894         val &= ~(NVM_CFG1_SPI_CLK_DIV | NVM_CFG1_SEE_CLK_DIV);
895         val |= (0x0<<7) | (0x6<<11);
896     }
897     else if(CHIP_REV(pdev) == CHIP_REV_IKOS)
898     {
899         val &= ~(NVM_CFG1_SPI_CLK_DIV | NVM_CFG1_SEE_CLK_DIV);
900         val |= (0x0<<7) | (0x0<<11);
901     }
902     else
903     {
904           /* No change, leave it */
905     }
906 
907     REG_WR(pdev, nvm.nvm_cfg1, val);
908     REG_WR(pdev, nvm.nvm_cfg2, cfg_table[idx].config2);
909     REG_WR(pdev, nvm.nvm_cfg3, cfg_table[idx].config3);
910     REG_WR(pdev, nvm.nvm_write1, cfg_table[idx].write1);
911 
912     /* Disable access to flash interface */
913     (void) disable_nvram_access(pdev);
914     release_nvram_lock(pdev);
915 
916 } /* lm_nvram_init */
917 
918 
919 /*******************************************************************************
920  * Description:
921  *
922  * Return:
923  ******************************************************************************/
924 u32_t
lm_nvram_query(lm_device_t * pdev,u8_t reset_flash_block,u8_t no_hw_mod)925 lm_nvram_query(
926     lm_device_t *pdev,
927     u8_t reset_flash_block,
928     u8_t no_hw_mod)
929 {
930     u32_t val;
931     u32_t j;
932     u32_t cnt, idx, ret_val = (u32_t)-1;
933     u8_t reconfigured = FALSE;
934     u32_t entry_count, mask;
935 
936 
937     DbgMessage(pdev, INFORM, "### lm_nvram_query\n");
938 
939     if (CHIP_NUM(pdev) == CHIP_NUM_5709)
940     {
941         REG_RD(pdev, nvm.nvm_cfg4, &val);
942 
943         pdev->hw_info.flash_spec.buffered   = 0;
944         pdev->hw_info.flash_spec.shift_bits = 0;
945         pdev->hw_info.flash_spec.page_size  = SAIFUN_FLASH_PAGE_SIZE;
946         pdev->hw_info.flash_spec.addr_mask  = 0;
947         pdev->hw_info.flash_spec.total_size = (1 << (val & 0x07)) * 1024 * 1024 / 8;
948         return (u32_t)-1;
949     }
950 
951     /* Adjust timeout for emulation/FPGA */
952     cnt = NVRAM_TIMEOUT_COUNT;
953     if(CHIP_REV(pdev) == CHIP_REV_FPGA) cnt *= 10;
954     else if(CHIP_REV(pdev) == CHIP_REV_IKOS) cnt *= 100;
955 
956     /* Reset the NVRAM interface block. */
957     if(reset_flash_block)
958     {
959         val = 0;
960 
961         /* Get access to write flash block register */
962         (void) enable_nvram_access(pdev);
963 
964         REG_WR(pdev, nvm.nvm_command, NVM_COMMAND_RST);
965         for(j = 0; j < cnt; j++)
966         {
967             mm_wait(pdev, 5);
968 
969             REG_RD(pdev, nvm.nvm_command, &val);
970             if(!(val & NVM_COMMAND_RST))
971             {
972                 break;
973             }
974         }
975 
976         DbgBreakIf(val & NVM_COMMAND_RST);
977     }
978 
979     /* Determine the selected interface. */
980     REG_RD(pdev, nvm.nvm_cfg1, &val);
981 
982     entry_count = sizeof(cfg_table)/sizeof(new_nvm_cfg_t);
983 
984     if (val & (1<<30))
985     {
986         /* Flash interface has been reconfigured */
987         mask = FLASH_BACKUP_STRAP_MASK;
988         for (idx=0; idx<entry_count; idx++)
989         {
990             if ((val & mask) == (cfg_table[idx].strapping & mask))
991             {
992                 DbgMessage(pdev, INFORM, "Reconfigured ");
993                 DbgMessage(pdev, INFORM, cfg_table[idx].name);
994                 DbgMessage(pdev, INFORM, " detected.\n");
995 
996                 reconfigured = TRUE;
997                 ret_val = idx;
998                 break;
999             }
1000         }
1001     }
1002     else
1003     {
1004         /* Not yet been reconfigured */
1005 
1006         /* A new bit to indicate where to look for strapping (backup vs. original) */
1007         mask = (val & (1<<23)) ? FLASH_BACKUP_STRAP_MASK : FLASH_STRAP_MASK;
1008 
1009         for (idx=0; idx<entry_count; idx++)
1010         {
1011 
1012             if ((val & mask) == (cfg_table[idx].strapping & mask))
1013             {
1014                 DbgMessage(pdev, INFORM, cfg_table[idx].name);
1015                 DbgMessage(pdev, INFORM, " detected.\n");
1016 
1017                 ret_val = idx;
1018                 break;
1019             }
1020         }
1021     } /* if (val & (1<<30)) */
1022 
1023     /* Check for exceptions: entries that are supported by TetonII B0,
1024      * but not earlier chips
1025      */
1026     if ((ret_val == 5) && (CHIP_ID(pdev) < CHIP_ID_5708_B0))
1027     {
1028         pdev->hw_info.flash_spec.total_size = 0;
1029 
1030         DbgBreakMsg("Unsupported type.\n");
1031     }
1032     else if (ret_val != (u32_t)-1)
1033     {
1034         /* Track what's been configured */
1035         pdev->hw_info.flash_spec.buffered   = cfg_table[ret_val].buffered;
1036         pdev->hw_info.flash_spec.shift_bits = cfg_table[ret_val].shift_bits;
1037         pdev->hw_info.flash_spec.page_size  = cfg_table[ret_val].page_size;
1038         pdev->hw_info.flash_spec.addr_mask  = cfg_table[ret_val].addr_mask;
1039         /* Determine the size before reconfiguring, dynamically */
1040         if (no_hw_mod)
1041         {
1042             pdev->hw_info.flash_spec.total_size = cfg_table[ret_val].total_size;
1043         }
1044         else
1045         {
1046             pdev->hw_info.flash_spec.total_size = find_nvram_size(pdev, idx);
1047         }
1048     }
1049     else
1050     {
1051         pdev->hw_info.flash_spec.total_size = 0;
1052 
1053         DbgBreakMsg("Unknown flash/EEPROM type.\n");
1054     }
1055 
1056     return (reconfigured) ? (u32_t)-1 : ret_val;
1057 
1058 } /* lm_nvram_query */
1059 
1060 
1061 
1062 /*******************************************************************************
1063  * Description:
1064  *
1065  * Return:
1066  ******************************************************************************/
1067 lm_status_t
lm_nvram_read(lm_device_t * pdev,u32_t offset,u32_t * ret_buf,u32_t buf_size)1068 lm_nvram_read(
1069     lm_device_t *pdev,
1070     u32_t offset,
1071     u32_t *ret_buf,
1072     u32_t buf_size)
1073 {
1074     lm_status_t lm_status;
1075     u32_t cmd_flags;
1076 
1077     DbgMessage(pdev, VERBOSE, "### lm_nvram_read\n");
1078 
1079     if((buf_size & 0x03) || (offset & 0x03))
1080     {
1081         DbgBreakMsg("Invalid paramter.\n");
1082 
1083         return LM_STATUS_FAILURE;
1084     }
1085     if(offset + buf_size > pdev->hw_info.flash_spec.total_size)
1086     {
1087         DbgBreakMsg("Invalid paramter.\n");
1088 
1089         return LM_STATUS_FAILURE;
1090     }
1091 
1092     if (pdev->hw_info.flash_spec.buffered)
1093     {
1094         cmd_flags = NVRAM_FLAG_BUFFERED_FLASH;
1095     }
1096     else
1097     {
1098         cmd_flags = NVRAM_FLAG_NONE;
1099     }
1100 
1101     /* Request access to the flash interface. */
1102     lm_status = acquire_nvram_lock(pdev);
1103     if(lm_status != LM_STATUS_SUCCESS)
1104     {
1105         return lm_status;
1106     }
1107 
1108     /* Enable access to flash interface */
1109     lm_status = enable_nvram_access(pdev);
1110     if(lm_status != LM_STATUS_SUCCESS)
1111     {
1112         return lm_status;
1113     }
1114 
1115     if(buf_size <= sizeof(u32_t))
1116     {
1117         /* Address of the NVRAM to read from. */
1118         cmd_flags |= NVRAM_FLAG_SET_FIRST_CMD_BIT |
1119             NVRAM_FLAG_SET_LAST_CMD_BIT;
1120         lm_status = nvram_read_dword(pdev, offset, ret_buf, cmd_flags);
1121     }
1122     else
1123     {
1124         /* Read the first word. */
1125         cmd_flags |= NVRAM_FLAG_SET_FIRST_CMD_BIT;
1126         lm_status = nvram_read_dword(pdev, offset, ret_buf, cmd_flags);
1127         cmd_flags &= ~NVRAM_FLAG_SET_FIRST_CMD_BIT;
1128         if(lm_status == LM_STATUS_SUCCESS)
1129         {
1130             /* Advance to the next dword. */
1131             offset += sizeof(u32_t);
1132             ret_buf++;
1133             buf_size -= sizeof(u32_t);
1134 
1135             while(buf_size > sizeof(u32_t) && lm_status == LM_STATUS_SUCCESS)
1136             {
1137                 lm_status = nvram_read_dword(pdev, offset, ret_buf, cmd_flags);
1138 
1139                 /* Advance to the next dword. */
1140                 offset += sizeof(u32_t);
1141                 ret_buf++;
1142                 buf_size -= sizeof(u32_t);
1143             }
1144 
1145             if(lm_status == LM_STATUS_SUCCESS)
1146             {
1147                 cmd_flags |= NVRAM_FLAG_SET_LAST_CMD_BIT;
1148                 lm_status = nvram_read_dword(pdev, offset, ret_buf, cmd_flags);
1149             }
1150         }
1151     }
1152 
1153     /* Disable access to flash interface */
1154     (void) disable_nvram_access(pdev);
1155 
1156     release_nvram_lock(pdev);
1157 
1158     return lm_status;
1159 } /* lm_nvram_read */
1160 
1161 /*******************************************************************************
1162  * Description:
1163  *
1164  * Return:
1165  ******************************************************************************/
1166 lm_status_t
lm_nvram_write(lm_device_t * pdev,u32_t offset,u32_t * data_buf,u32_t buf_size)1167 lm_nvram_write(
1168     lm_device_t *pdev,
1169     u32_t offset,
1170     u32_t *data_buf,
1171     u32_t buf_size)
1172 {
1173     lm_status_t lm_status;
1174     u32_t cmd_flags;
1175     u32_t written_so_far, page_start, page_end, data_start, data_end;
1176     u32_t idx, *ptr32, addr, base_flags;
1177     static u32_t flash_buffer[66];
1178 
1179     DbgMessage(pdev, VERBOSE, "### lm_nvram_write\n");
1180 
1181     if(offset & 0x03)
1182     {
1183         DbgBreakMsg("Invalid paramter.\n");
1184 
1185         return LM_STATUS_FAILURE;
1186     }
1187 
1188     if(offset + buf_size > pdev->hw_info.flash_spec.total_size)
1189     {
1190         DbgBreakMsg("Invalid paramter.\n");
1191         return LM_STATUS_FAILURE;
1192     }
1193 
1194     lm_status = LM_STATUS_SUCCESS;
1195 
1196     written_so_far = 0;
1197     ptr32 = data_buf;
1198 
1199     if ((CHIP_NUM(pdev) == CHIP_NUM_5706) || (CHIP_NUM(pdev) == CHIP_NUM_5708))
1200     {
1201         base_flags = (pdev->hw_info.flash_spec.buffered) ?
1202                      NVRAM_FLAG_BUFFERED_FLASH : NVRAM_FLAG_NONE;
1203         while (written_so_far < buf_size)
1204         {
1205             /* Find the page_start addr */
1206             page_start = offset + written_so_far;
1207             page_start -= (page_start % pdev->hw_info.flash_spec.page_size);
1208             /* Find the page_end addr */
1209             page_end = page_start + pdev->hw_info.flash_spec.page_size;
1210             /* Find the data_start addr */
1211             data_start = (written_so_far==0) ?  offset : page_start;
1212             /* Find the data_end addr */
1213             data_end = (page_end > offset + buf_size) ?
1214                        (offset+buf_size) : page_end;
1215 
1216             /* Request access to the flash interface. */
1217             lm_status = acquire_nvram_lock(pdev);
1218             if(lm_status != LM_STATUS_SUCCESS) return lm_status;
1219 
1220             /* Enable access to flash interface */
1221             lm_status = enable_nvram_access(pdev);
1222             if(lm_status != LM_STATUS_SUCCESS) return lm_status;
1223 
1224             if (pdev->hw_info.flash_spec.buffered == 0)
1225             {
1226                 /* Read the whole page into the buffer (non-buffer flash only) */
1227                 for (idx=0; idx<pdev->hw_info.flash_spec.page_size; idx+=4)
1228                 {
1229                     cmd_flags = base_flags;
1230                     if (idx==0)
1231                     {
1232                         cmd_flags |= NVRAM_FLAG_SET_FIRST_CMD_BIT;
1233                     }
1234                     if (idx==pdev->hw_info.flash_spec.page_size-4)
1235                     {
1236                         cmd_flags |= NVRAM_FLAG_SET_LAST_CMD_BIT;
1237                     }
1238                     lm_status |= nvram_read_dword(pdev, page_start+idx,
1239                                                   &flash_buffer[idx/4],
1240                                                   cmd_flags);
1241                 }
1242                 if(lm_status != LM_STATUS_SUCCESS) return lm_status;
1243             }
1244 
1245             /* Enable writes to flash interface (unlock write-protect) */
1246             lm_status = enable_nvram_write(pdev);
1247             if(lm_status != LM_STATUS_SUCCESS) return lm_status;
1248 
1249             /* Erase the page */
1250             lm_status = nvram_erase_page(pdev, page_start);
1251             if(lm_status != LM_STATUS_SUCCESS) return lm_status;
1252 
1253             /* Re-enable the write again for the actual write */
1254             lm_status = enable_nvram_write(pdev);
1255             if(lm_status != LM_STATUS_SUCCESS) return lm_status;
1256 
1257             /* Loop to write back the buffer data from page_start to data_start */
1258             cmd_flags = NVRAM_FLAG_SET_FIRST_CMD_BIT | base_flags;
1259             idx = 0;
1260             for (addr=page_start; addr<data_start; addr+=4, idx++)
1261             {
1262                 if (pdev->hw_info.flash_spec.buffered == 0)
1263                 {
1264                     /* Write back only for non-buffered flash */
1265                     (void) nvram_write_dword(pdev, addr, flash_buffer[idx], cmd_flags);
1266                     cmd_flags = base_flags;
1267                 }
1268             }
1269 
1270             /* Loop to write the new data from data_start to data_end */
1271             for (addr=data_start; addr<data_end; addr+=4, idx++)
1272             {
1273                 if ((addr==page_end-4) ||
1274                     ((pdev->hw_info.flash_spec.buffered) && (addr>=data_end-4)))
1275                 {
1276                     /* End of a page (page_end==data_end)
1277                      * OR end of new data (in buffered flash case) */
1278                     cmd_flags |= NVRAM_FLAG_SET_LAST_CMD_BIT;
1279                 }
1280                 (void) nvram_write_dword(pdev, addr, *ptr32, cmd_flags);
1281                 cmd_flags = base_flags;
1282                 ptr32++;
1283             }
1284 
1285             /* Loop to write back the buffer data from data_end to page_end */
1286             for (addr=data_end; addr<page_end; addr+=4, idx++)
1287             {
1288                 if (pdev->hw_info.flash_spec.buffered == 0)
1289                 {
1290                     /* Write back only for non-buffered flash */
1291                     if (addr == page_end-4)
1292                     {
1293                         cmd_flags = NVRAM_FLAG_SET_LAST_CMD_BIT | base_flags;
1294                     }
1295                     (void) nvram_write_dword(pdev, addr, flash_buffer[idx], cmd_flags);
1296                     cmd_flags = base_flags;
1297                 }
1298             }
1299 
1300             /* Disable writes to flash interface (lock write-protect) */
1301             (void) disable_nvram_write(pdev);
1302 
1303             /* Disable access to flash interface */
1304             (void) disable_nvram_access(pdev);
1305             release_nvram_lock(pdev);
1306 
1307             /* Increment written_so_far */
1308             written_so_far += data_end - data_start;
1309         } // while
1310     }
1311     else if (CHIP_NUM(pdev) == CHIP_NUM_5709)
1312     {
1313         /* Request access to the flash interface. */
1314         lm_status = acquire_nvram_lock(pdev);
1315         if(lm_status != LM_STATUS_SUCCESS) return lm_status;
1316 
1317         /* Enable access to flash interface */
1318         lm_status = enable_nvram_access(pdev);
1319         if(lm_status != LM_STATUS_SUCCESS) return lm_status;
1320 
1321         cmd_flags = NVRAM_FLAG_SET_FIRST_CMD_BIT;
1322         addr = offset;
1323         while (written_so_far < buf_size)
1324         {
1325             if (written_so_far == (buf_size - 4))
1326                 cmd_flags |= NVRAM_FLAG_SET_LAST_CMD_BIT;
1327             else if (((addr & 0xff) + 4) == 256)
1328                 cmd_flags |= NVRAM_FLAG_SET_LAST_CMD_BIT;
1329             if ((addr & 0xff) == 0)
1330                 cmd_flags |= NVRAM_FLAG_SET_FIRST_CMD_BIT;
1331             (void) nvram_write_dword(pdev, addr, *ptr32, cmd_flags);
1332             ptr32++;
1333             addr += 4;
1334             written_so_far += 4;
1335             cmd_flags = 0;
1336         }
1337         /* Disable access to flash interface */
1338         (void) disable_nvram_access(pdev);
1339         release_nvram_lock(pdev);
1340     }
1341 
1342     return lm_status;
1343 
1344 } /* lm_nvram_write */
1345