1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 QLogic Corporation. All rights reserved.
24 */
25
26 #include <qlge.h>
27 /*
28 * Local Function Prototypes.
29 */
30 static int ql_read_flash(qlge_t *, uint32_t, uint32_t *);
31 static int ql_write_flash(qlge_t *, uint32_t, uint32_t);
32 static int ql_protect_flash(qlge_t *);
33 static int ql_unprotect_flash(qlge_t *);
34
35 /*
36 * ql_flash_id
37 * The flash memory chip exports 3 ID bytes in the order of manufacturer, id,
38 * capability
39 */
40 int
41 ql_flash_id(qlge_t *qlge)
42 {
43 int rval;
44 uint32_t fdata = 0;
45
46 /*
47 * Send Restore command (0xAB) to release Flash from
48 * possible deep power down state
49 */
50 rval = ql_read_flash(qlge, FLASH_CONF_ADDR | 0x300 | FLASH_RES_CMD,
51 &fdata);
52 QL_PRINT(DBG_FLASH, ("%s(%d) flash electronic signature is %x \n",
53 __func__, qlge->instance, fdata));
54 fdata = 0;
55
56 /* 0x9F */
57 rval = ql_read_flash(qlge, FLASH_CONF_ADDR | 0x0400 | FLASH_RDID_CMD,
58 &fdata);
59
60 if ((rval != DDI_SUCCESS) || (fdata == 0)) {
61 cmn_err(CE_WARN, "%s(%d) read_flash failed 0x%x.",
62 __func__, qlge->instance, fdata);
63 } else {
64 qlge->flash_info.flash_manuf = LSB(LSW(fdata));
65 qlge->flash_info.flash_id = MSB(LSW(fdata));
66 qlge->flash_info.flash_cap = LSB(MSW(fdata));
67 QL_PRINT(DBG_FLASH, ("%s(%d) flash manufacturer 0x%x,"
68 " flash id 0x%x, flash cap 0x%x\n",
69 __func__, qlge->instance,
70 qlge->flash_info.flash_manuf, qlge->flash_info.flash_id,
71 qlge->flash_info.flash_cap));
72 }
73 return (rval);
74 }
75
76 /*
77 * qlge_dump_fcode
78 * Dumps fcode from flash.
79 */
80 int
81 qlge_dump_fcode(qlge_t *qlge, uint8_t *dp, uint32_t size, uint32_t startpos)
82 {
83 uint32_t cnt, data, addr;
84 int rval = DDI_SUCCESS;
85
86 QL_PRINT(DBG_FLASH, ("%s(%d) entered to read address %x, %x bytes\n",
87 __func__, qlge->instance, startpos, size));
88
89 /* make sure startpos+size doesn't exceed flash */
90 if (size + startpos > qlge->fdesc.flash_size) {
91 cmn_err(CE_WARN, "%s(%d) exceeded flash range, sz=%xh, stp=%xh,"
92 " flsz=%xh", __func__, qlge->instance,
93 size, startpos, qlge->fdesc.flash_size);
94 return (DDI_FAILURE);
95 }
96
97 /* check start addr is 32 bit or 4 byte aligned for M25Pxx */
98 if ((startpos & 0x3) != 0) {
99 cmn_err(CE_WARN, "%s(%d) incorrect buffer size alignment",
100 __func__, qlge->instance);
101 return (DDI_FAILURE);
102 }
103
104 /* adjust flash start addr for 32 bit words */
105 addr = startpos / 4;
106
107 /* Read fcode data from flash. */
108 cnt = startpos;
109 size += startpos;
110 while (cnt < size) {
111 /* Allow other system activity. */
112 if (cnt % 0x1000 == 0) {
113 drv_usecwait(1);
114 }
115 rval = ql_read_flash(qlge, addr++, &data);
116 if (rval != DDI_SUCCESS) {
117 break;
118 }
119 *dp++ = LSB(LSW(data));
120 *dp++ = MSB(LSW(data));
121 *dp++ = LSB(MSW(data));
122 *dp++ = MSB(MSW(data));
123 cnt += 4;
124 }
125
126 if (rval != DDI_SUCCESS) {
127 cmn_err(CE_WARN, "failed, rval = %xh", rval);
128 }
129 return (rval);
130 }
131
132 int
133 ql_erase_and_write_to_flash(qlge_t *qlge, uint8_t *dp, uint32_t size,
134 uint32_t faddr)
135 {
136 int rval = DDI_FAILURE;
137 uint32_t cnt, rest_addr, fdata;
138
139 QL_PRINT(DBG_FLASH, ("%s(%d) entered to write addr %x, %d bytes\n",
140 __func__, qlge->instance, faddr, size));
141
142 /* start address must be 32 bit word aligned */
143 if ((faddr & 0x3) != 0) {
144 cmn_err(CE_WARN, "%s(%d) incorrect buffer size alignment",
145 __func__, qlge->instance);
146 return (DDI_FAILURE);
147 }
148
149 /* setup mask of address range within a sector */
150 rest_addr = (qlge->fdesc.block_size - 1) >> 2;
151
152 faddr = faddr >> 2; /* flash gets 32 bit words */
153
154 /*
155 * Write data to flash.
156 */
157 cnt = 0;
158 size = (size + 3) >> 2; /* Round up & convert to dwords */
159 while (cnt < size) {
160 /* Beginning of a sector? do a sector erase */
161 if ((faddr & rest_addr) == 0) {
162 fdata = (faddr & ~rest_addr) << 2;
163 fdata = (fdata & 0xff00) |
164 (fdata << 16 & 0xff0000) |
165 (fdata >> 16 & 0xff);
166 /* 64k bytes sector erase */
167 rval = ql_write_flash(qlge, /* 0xd8 */
168 FLASH_CONF_ADDR | 0x0300 | qlge->fdesc.erase_cmd,
169 fdata);
170
171 if (rval != DDI_SUCCESS) {
172 cmn_err(CE_WARN, "Unable to flash sector: "
173 "address=%xh", faddr);
174 goto out;
175 }
176 }
177 /* Write data */
178 fdata = *dp++;
179 fdata |= *dp++ << 8;
180 fdata |= *dp++ << 16;
181 fdata |= *dp++ << 24;
182
183 rval = ql_write_flash(qlge, faddr, fdata);
184 if (rval != DDI_SUCCESS) {
185 cmn_err(CE_WARN, "Unable to program flash "
186 "address=%xh data=%xh", faddr,
187 *dp);
188 goto out;
189 }
190 cnt++;
191 faddr++;
192
193 /* Allow other system activity. */
194 if (cnt % 0x1000 == 0) {
195 qlge_delay(10000);
196 }
197 }
198 rval = DDI_SUCCESS;
199 out:
200 if (rval != DDI_SUCCESS) {
201 cmn_err(CE_WARN, "%s(%d failed=%xh",
202 __func__, qlge->instance, rval);
203 }
204 return (rval);
205 }
206
207 void
208 get_sector_number(qlge_t *qlge, uint32_t faddr, uint32_t *psector)
209 {
210 *psector = faddr / qlge->fdesc.block_size; /* 0x10000 */
211 }
212
213 /*
214 * qlge_load_flash
215 * Write "size" bytes from memory "dp" to flash address "faddr".
216 * faddr = 32bit word flash address.
217 */
218 int
219 qlge_load_flash(qlge_t *qlge, uint8_t *dp, uint32_t len, uint32_t faddr)
220 {
221 int rval = DDI_FAILURE;
222 uint32_t start_block, end_block;
223 uint32_t start_byte, end_byte;
224 uint32_t num;
225 uint32_t sector_size, addr_src, addr_desc;
226 uint8_t *temp;
227 caddr_t bp, bdesc;
228
229 QL_PRINT(DBG_FLASH, ("%s(%d) entered to write addr %x, %d bytes\n",
230 __func__, qlge->instance, faddr, len));
231
232 sector_size = qlge->fdesc.block_size;
233
234 if (faddr > qlge->fdesc.flash_size) {
235 cmn_err(CE_WARN, "%s(%d): invalid flash write address %x",
236 __func__, qlge->instance, faddr);
237 return (DDI_FAILURE);
238 }
239 /* Get semaphore to access Flash Address and Flash Data Registers */
240 if (ql_sem_spinlock(qlge, QL_FLASH_SEM_MASK) != DDI_SUCCESS) {
241 return (DDI_FAILURE);
242 }
243 temp = kmem_zalloc(sector_size, KM_SLEEP);
244
245 (void) ql_unprotect_flash(qlge);
246
247 get_sector_number(qlge, faddr, &start_block);
248 get_sector_number(qlge, faddr + len - 1, &end_block);
249
250 QL_PRINT(DBG_FLASH, ("%s(%d) start_block %x, end_block %x\n",
251 __func__, qlge->instance, start_block, end_block));
252
253 for (num = start_block; num <= end_block; num++) {
254 QL_PRINT(DBG_FLASH,
255 ("%s(%d) sector_size 0x%x, sector read addr %x\n",
256 __func__, qlge->instance, sector_size, num * sector_size));
257 /* read one whole sector flash data to buffer */
258 rval = qlge_dump_fcode(qlge, (uint8_t *)temp, sector_size,
259 num * sector_size);
260
261 start_byte = num * sector_size;
262 end_byte = start_byte + sector_size -1;
263 if (start_byte < faddr)
264 start_byte = faddr;
265 if (end_byte > (faddr + len))
266 end_byte = (faddr + len - 1);
267
268 addr_src = start_byte - faddr;
269 addr_desc = start_byte - num * sector_size;
270 bp = (caddr_t)dp + addr_src;
271 bdesc = (caddr_t)temp + addr_desc;
272 bcopy(bp, bdesc, (end_byte - start_byte + 1));
273
274 /* write the whole sector data to flash */
275 if (ql_erase_and_write_to_flash(qlge, temp, sector_size,
276 num * sector_size) != DDI_SUCCESS)
277 goto out;
278 }
279 rval = DDI_SUCCESS;
280 out:
281 (void) ql_protect_flash(qlge);
282 kmem_free(temp, sector_size);
283
284 ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
285
286 if (rval != DDI_SUCCESS) {
287 cmn_err(CE_WARN, "%s(%d failed=%xh",
288 __func__, qlge->instance, rval);
289 }
290
291 return (rval);
292 }
293
294
295 /*
296 * ql_check_pci
297 * checks the passed buffer for a valid pci signature and
298 * expected (and in range) pci length values.
299 * On successful pci check, nextpos adjusted to next pci header.
300 */
301 static int
302 ql_check_pci(qlge_t *qlge, uint8_t *buf, uint32_t *nextpos)
303 {
304 pci_header_t *pcih;
305 pci_data_t *pcid;
306 uint32_t doff;
307 uint8_t *pciinfo;
308 uint32_t image_size = 0;
309 int rval = CONTINUE_SEARCH;
310
311 QL_PRINT(DBG_FLASH, ("%s(%d) check image at 0x%x\n",
312 __func__, qlge->instance, *nextpos));
313
314 if (buf != NULL) {
315 pciinfo = buf;
316 } else {
317 cmn_err(CE_WARN, "%s(%d) failed, null buf ptr passed",
318 __func__, qlge->instance);
319 return (STOP_SEARCH);
320 }
321
322 /* get the pci header image length */
323 pcih = (pci_header_t *)pciinfo;
324
325 doff = pcih->dataoffset[1];
326 doff <<= 8;
327 doff |= pcih->dataoffset[0];
328
329 /* some header section sanity check */
330 if (pcih->signature[0] != PCI_HEADER0 /* '55' */ ||
331 pcih->signature[1] != PCI_HEADER1 /* 'AA' */ || doff > 50) {
332 cmn_err(CE_WARN, "%s(%d) image format error: s0=%xh, s1=%xh,"
333 "off=%xh\n", __func__, qlge->instance,
334 pcih->signature[0], pcih->signature[1], doff);
335 return (STOP_SEARCH);
336 }
337
338 pcid = (pci_data_t *)(pciinfo + doff);
339
340 /* a slight sanity data section check */
341 if (pcid->signature[0] != 'P' || pcid->signature[1] != 'C' ||
342 pcid->signature[2] != 'I' || pcid->signature[3] != 'R') {
343 cmn_err(CE_WARN, "%s(%d) failed, data sig mismatch!",
344 __func__, qlge->instance);
345 return (STOP_SEARCH);
346 }
347 image_size =
348 (pcid->imagelength[0] | (pcid->imagelength[1] << 8))*
349 PCI_SECTOR_SIZE /* 512 */;
350
351 switch (pcid->codetype) {
352 case PCI_CODE_X86PC:
353 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_BIOS \n",
354 __func__, qlge->instance));
355 break;
356 case PCI_CODE_FCODE:
357 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_FCODE \n",
358 __func__, qlge->instance));
359 break;
360 case PCI_CODE_EFI:
361 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_EFI \n",
362 __func__, qlge->instance));
363 break;
364 case PCI_CODE_HPPA:
365 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is PCI_CODE_HPPA \n",
366 __func__, qlge->instance));
367 break;
368 default:
369 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_UNKNOWN \n",
370 __func__, qlge->instance));
371 break;
372 }
373
374 QL_PRINT(DBG_FLASH, ("%s(%d) image size %x at %x\n",
375 __func__, qlge->instance, image_size, *nextpos));
376
377 if (pcid->indicator == PCI_IND_LAST_IMAGE) {
378 QL_PRINT(DBG_FLASH, ("%s(%d) last boot image found \n",
379 __func__, qlge->instance));
380 rval = LAST_IMAGE_FOUND;
381 } else {
382 rval = CONTINUE_SEARCH;
383 }
384 /* Get the next flash image address */
385 *nextpos += image_size;
386
387 return (rval);
388 }
389
390 /*
391 * ql_find_flash_layout_table_data_structure
392 * Find Flash Layout Table Data Structure (FLTDS) that
393 * is located at the end of last boot image.
394 * Assume FLTDS is located with first 2M bytes.
395 * Note:
396 * Driver must be in stalled state prior to entering or
397 * add code to this function prior to calling ql_setup_flash()
398 */
399 int
400 ql_find_flash_layout_table_data_structure_addr(qlge_t *qlge)
401 {
402 int rval = DDI_FAILURE;
403 int result = CONTINUE_SEARCH;
404 uint32_t freadpos = 0;
405 uint8_t buf[FBUFSIZE];
406
407 if (qlge->flash_fltds_addr != 0) {
408 QL_PRINT(DBG_FLASH, ("%s(%d) done already\n",
409 __func__, qlge->instance));
410 return (DDI_SUCCESS);
411 }
412 /*
413 * Temporarily set the fdesc.flash_size to
414 * 1M flash size to avoid failing of ql_dump_focde.
415 */
416 qlge->fdesc.flash_size = FLASH_FIRMWARE_IMAGE_ADDR;
417
418 while (result == CONTINUE_SEARCH) {
419
420 if ((rval = qlge_dump_fcode(qlge, buf, FBUFSIZE, freadpos))
421 != DDI_SUCCESS) {
422 cmn_err(CE_WARN, "%s(%d) qlge_dump_fcode failed"
423 " pos=%xh rval=%xh",
424 __func__, qlge->instance, freadpos, rval);
425 break;
426 }
427 /*
428 * checkout the pci boot image format
429 * and get next read address
430 */
431 result = ql_check_pci(qlge, buf, &freadpos);
432 /*
433 * find last image? If so, then the freadpos
434 * is the address of FLTDS
435 */
436 if (result == LAST_IMAGE_FOUND) {
437 QL_PRINT(DBG_FLASH,
438 ("%s(%d) flash layout table data structure "
439 "(FLTDS) address is at %x \n", __func__,
440 qlge->instance, freadpos));
441 qlge->flash_fltds_addr = freadpos;
442 rval = DDI_SUCCESS;
443 break;
444 } else if (result == STOP_SEARCH) {
445 cmn_err(CE_WARN, "%s(%d) flash header incorrect,"
446 "stop searching",
447 __func__, qlge->instance);
448 break;
449 }
450 }
451 return (rval);
452 }
453
454 /*
455 * ql_flash_fltds
456 * Get flash layout table data structure table.
457 */
458 static int
459 ql_flash_fltds(qlge_t *qlge)
460 {
461 uint32_t cnt;
462 uint16_t chksum, *bp, data;
463 int rval;
464
465 rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->fltds,
466 sizeof (ql_fltds_t), qlge->flash_fltds_addr);
467 if (rval != DDI_SUCCESS) {
468 cmn_err(CE_WARN, "%s(%d)read error",
469 __func__, qlge->instance);
470 bzero(&qlge->fltds, sizeof (ql_fltds_t));
471 return (rval);
472 }
473
474 QL_DUMP(DBG_FLASH, "flash layout table data structure:\n",
475 &qlge->fltds, 8, sizeof (ql_fltds_t));
476
477 chksum = 0;
478 data = 0;
479 bp = (uint16_t *)&qlge->fltds;
480 for (cnt = 0; cnt < (sizeof (ql_fltds_t)) / 2; cnt++) {
481 data = *bp;
482 LITTLE_ENDIAN_16(&data);
483 chksum += data;
484 bp++;
485 }
486
487 LITTLE_ENDIAN_32(&qlge->fltds.signature);
488 LITTLE_ENDIAN_16(&qlge->fltds.flt_addr_lo);
489 LITTLE_ENDIAN_16(&qlge->fltds.flt_addr_hi);
490 LITTLE_ENDIAN_16(&qlge->fltds.checksum);
491
492 QL_PRINT(DBG_FLASH, ("%s(%d) signature %xh\n",
493 __func__, qlge->instance, qlge->fltds.signature));
494 QL_PRINT(DBG_FLASH, ("%s(%d) flt_addr_lo %xh\n",
495 __func__, qlge->instance, qlge->fltds.flt_addr_lo));
496 QL_PRINT(DBG_FLASH, ("%s(%d) flt_addr_hi %xh\n",
497 __func__, qlge->instance, qlge->fltds.flt_addr_hi));
498 QL_PRINT(DBG_FLASH, ("%s(%d) version %xh\n",
499 __func__, qlge->instance, qlge->fltds.version));
500 QL_PRINT(DBG_FLASH, ("%s(%d) checksum %xh\n",
501 __func__, qlge->instance, qlge->fltds.checksum));
502 /* QFLT */
503 if (chksum != 0 || qlge->fltds.signature != FLASH_FLTDS_SIGNATURE) {
504 cmn_err(CE_WARN, "%s(%d) invalid flash layout table data"
505 " structure", __func__, qlge->instance);
506 bzero(&qlge->fltds, sizeof (ql_fltds_t));
507 return (DDI_FAILURE);
508 }
509 return (DDI_SUCCESS);
510 }
511
512 /*
513 * ql_flash_flt
514 * Get flash layout table.
515 */
516 int
517 ql_flash_flt(qlge_t *qlge)
518 {
519 uint32_t addr, cnt;
520 int rval = DDI_FAILURE;
521 ql_flt_entry_t *entry;
522 uint8_t region;
523
524 addr = qlge->fltds.flt_addr_hi;
525 addr <<= 16;
526 addr |= qlge->fltds.flt_addr_lo;
527
528 /* first read flt header to know how long the table is */
529 rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->flt.header,
530 sizeof (ql_flt_header_t), addr);
531 if (rval != DDI_SUCCESS) {
532 cmn_err(CE_WARN, "%s(%d) read flt header at %x error",
533 __func__, qlge->instance, addr);
534 bzero(&qlge->flt, sizeof (ql_flt_header_t));
535 return (rval);
536 }
537
538 LITTLE_ENDIAN_16(&qlge->flt.header.version);
539 LITTLE_ENDIAN_16(&qlge->flt.header.length);
540 LITTLE_ENDIAN_16(&qlge->flt.header.checksum);
541 LITTLE_ENDIAN_16(&qlge->flt.header.reserved);
542
543 if ((qlge->flt.header.version != 1) &&
544 (qlge->flt.header.version != 0)) {
545 cmn_err(CE_WARN, "%s(%d) flt header version %x unsupported",
546 __func__, qlge->instance, qlge->flt.header.version);
547 bzero(&qlge->flt, sizeof (ql_flt_header_t));
548 return (DDI_FAILURE);
549 }
550 /* 2.allocate memory to save all flt table entries */
551 if ((qlge->flt.ql_flt_entry_ptr = (ql_flt_entry_t *)
552 (kmem_zalloc(qlge->flt.header.length, KM_SLEEP))) == NULL) {
553 cmn_err(CE_WARN, "%s(%d) flt table alloc failed",
554 __func__, qlge->instance);
555 goto err;
556 }
557 /* how many tables? */
558 qlge->flt.num_entries = (uint16_t)(qlge->flt.header.length /
559 sizeof (ql_flt_entry_t));
560
561 /* 3. read the rest of flt table */
562 addr += (uint32_t)sizeof (ql_flt_header_t);
563 QL_PRINT(DBG_FLASH, ("%s(%d) flt has %x entries \n",
564 __func__, qlge->instance, qlge->flt.num_entries));
565 rval = qlge_dump_fcode(qlge,
566 (uint8_t *)qlge->flt.ql_flt_entry_ptr, qlge->flt.header.length,
567 addr);
568 if (rval != DDI_SUCCESS) {
569 cmn_err(CE_WARN, "read flt table entry error");
570 goto err;
571 }
572
573 entry = (ql_flt_entry_t *)qlge->flt.ql_flt_entry_ptr;
574 for (cnt = 0; cnt < qlge->flt.num_entries; cnt++) {
575 LITTLE_ENDIAN_32(&entry->size);
576 LITTLE_ENDIAN_32(&entry->begin_addr);
577 LITTLE_ENDIAN_32(&entry->end_addr);
578 entry++;
579 }
580 /* TO Do :4. Checksum verification */
581
582 /* 5.search index of Flash Descriptor Table in the Flash Layout Table */
583 entry = (ql_flt_entry_t *)qlge->flt.ql_flt_entry_ptr;
584 qlge->flash_fdt_addr = 0;
585 for (cnt = 0; cnt < qlge->flt.num_entries; cnt++) {
586 if (entry->region == FLT_REGION_FDT) {
587 qlge->flash_flt_fdt_index = cnt;
588 qlge->flash_fdt_addr = entry->begin_addr;
589 qlge->flash_fdt_size = entry->size;
590 QL_PRINT(DBG_FLASH, ("%s(%d) flash_flt_fdt_index is"
591 " %x, addr %x,size %x \n", __func__,
592 qlge->instance,
593 cnt, entry->begin_addr, entry->size));
594 break;
595 }
596 entry++;
597 }
598
599 if (qlge->flash_fdt_addr == 0) {
600 cmn_err(CE_WARN, "%s(%d) flash descriptor table not found",
601 __func__, qlge->instance);
602 goto err;
603 }
604 /* 6.search index of Nic Config. Table in the Flash Layout Table */
605 entry = (ql_flt_entry_t *)qlge->flt.ql_flt_entry_ptr;
606 if (qlge->func_number == qlge->fn0_net)
607 region = FLT_REGION_NIC_PARAM0;
608 else
609 region = FLT_REGION_NIC_PARAM1;
610 qlge->flash_nic_config_table_addr = 0;
611 for (cnt = 0; cnt < qlge->flt.num_entries; cnt++) {
612 if (entry->region == region) {
613 qlge->flash_flt_nic_config_table_index = cnt;
614 qlge->flash_nic_config_table_addr = entry->begin_addr;
615 qlge->flash_nic_config_table_size = entry->size;
616 QL_PRINT(DBG_FLASH, ("%s(%d) "
617 "flash_flt_nic_config_table_index "
618 "is %x, address %x, size %x \n",
619 __func__, qlge->instance,
620 cnt, entry->begin_addr, entry->size));
621 break;
622 }
623 entry++;
624 }
625 if (qlge->flash_nic_config_table_addr == 0) {
626 cmn_err(CE_WARN, "%s(%d) NIC Configuration Table not found",
627 __func__, qlge->instance);
628 goto err;
629 }
630
631 return (DDI_SUCCESS);
632 err:
633 bzero(&qlge->flt, sizeof (ql_flt_header_t));
634 if (qlge->flt.ql_flt_entry_ptr != NULL) {
635 bzero(&qlge->flt.ql_flt_entry_ptr, qlge->flt.header.length);
636 kmem_free(qlge->flt.ql_flt_entry_ptr, qlge->flt.header.length);
637 qlge->flt.ql_flt_entry_ptr = NULL;
638 }
639 cmn_err(CE_WARN, "%s(%d) read FLT failed", __func__, qlge->instance);
640 return (DDI_FAILURE);
641 }
642
643 /*
644 * ql_flash_desc
645 * Get flash descriptor table.
646 */
647 static int
648 ql_flash_desc(qlge_t *qlge)
649 {
650 uint8_t w8;
651 uint32_t cnt, addr;
652 uint16_t chksum, *bp, data;
653 int rval;
654
655 addr = qlge->flash_fdt_addr;
656
657 rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->fdesc,
658 sizeof (flash_desc_t), addr);
659 if (rval != DDI_SUCCESS) {
660 cmn_err(CE_WARN, "%s(%d) read Flash Descriptor Table error",
661 __func__, qlge->instance);
662 bzero(&qlge->fdesc, sizeof (flash_desc_t));
663 return (rval);
664 }
665
666 chksum = 0;
667 data = 0;
668 bp = (uint16_t *)&qlge->fdesc;
669 for (cnt = 0; cnt < (sizeof (flash_desc_t)) / 2; cnt++) {
670 data = *bp;
671 LITTLE_ENDIAN_16(&data);
672 chksum += data;
673 bp++;
674 }
675 /* endian adjustment */
676 LITTLE_ENDIAN_32(&qlge->fdesc.flash_valid);
677 LITTLE_ENDIAN_16(&qlge->fdesc.flash_version);
678 LITTLE_ENDIAN_16(&qlge->fdesc.flash_len);
679 LITTLE_ENDIAN_16(&qlge->fdesc.flash_checksum);
680 LITTLE_ENDIAN_16(&qlge->fdesc.flash_unused);
681 LITTLE_ENDIAN_16(&qlge->fdesc.flash_manuf);
682 LITTLE_ENDIAN_16(&qlge->fdesc.flash_id);
683 LITTLE_ENDIAN_32(&qlge->fdesc.block_size);
684 LITTLE_ENDIAN_32(&qlge->fdesc.alt_block_size);
685 LITTLE_ENDIAN_32(&qlge->fdesc.flash_size);
686 LITTLE_ENDIAN_32(&qlge->fdesc.write_enable_data);
687 LITTLE_ENDIAN_32(&qlge->fdesc.read_timeout);
688
689 /* flash size in desc table is in 1024 bytes */
690 QL_PRINT(DBG_FLASH, ("flash_valid=%xh\n", qlge->fdesc.flash_valid));
691 QL_PRINT(DBG_FLASH, ("flash_version=%xh\n", qlge->fdesc.flash_version));
692 QL_PRINT(DBG_FLASH, ("flash_len=%xh\n", qlge->fdesc.flash_len));
693 QL_PRINT(DBG_FLASH, ("flash_checksum=%xh\n",
694 qlge->fdesc.flash_checksum));
695
696 w8 = qlge->fdesc.flash_model[15];
697 qlge->fdesc.flash_model[15] = 0;
698 QL_PRINT(DBG_FLASH, ("flash_model=%s\n", qlge->fdesc.flash_model));
699 qlge->fdesc.flash_model[15] = w8;
700 QL_PRINT(DBG_FLASH, ("flash_size=%xK bytes\n", qlge->fdesc.flash_size));
701 qlge->fdesc.flash_size = qlge->fdesc.flash_size * 0x400;
702 qlge->flash_info.flash_size = qlge->fdesc.flash_size;
703
704 if (chksum != 0 || qlge->fdesc.flash_valid != FLASH_DESC_VAILD ||
705 qlge->fdesc.flash_version != FLASH_DESC_VERSION) {
706 cmn_err(CE_WARN, "invalid descriptor table");
707 bzero(&qlge->fdesc, sizeof (flash_desc_t));
708 return (DDI_FAILURE);
709 }
710
711 return (DDI_SUCCESS);
712 }
713
714 /*
715 * ql_flash_nic_config
716 * Get flash NIC Configuration table.
717 */
718 static int
719 ql_flash_nic_config(qlge_t *qlge)
720 {
721 uint32_t cnt, addr;
722 uint16_t chksum, *bp, data;
723 int rval;
724
725 addr = qlge->flash_nic_config_table_addr;
726
727 rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->nic_config,
728 sizeof (ql_nic_config_t), addr);
729
730 if (rval != DDI_SUCCESS) {
731 cmn_err(CE_WARN, "fail to read nic_cfg image %xh", rval);
732 bzero(&qlge->nic_config, sizeof (ql_nic_config_t));
733 return (rval);
734 }
735
736 chksum = 0;
737 data = 0;
738 bp = (uint16_t *)&qlge->nic_config;
739 for (cnt = 0; cnt < (sizeof (ql_nic_config_t)) / 2; cnt++) {
740 data = *bp;
741 LITTLE_ENDIAN_16(&data);
742 chksum += data;
743 bp++;
744 }
745
746 LITTLE_ENDIAN_32(&qlge->nic_config.signature);
747 LITTLE_ENDIAN_16(&qlge->nic_config.version);
748 LITTLE_ENDIAN_16(&qlge->nic_config.size);
749 LITTLE_ENDIAN_16(&qlge->nic_config.checksum);
750 LITTLE_ENDIAN_16(&qlge->nic_config.total_data_size);
751 LITTLE_ENDIAN_16(&qlge->nic_config.num_of_entries);
752 LITTLE_ENDIAN_16(&qlge->nic_config.vlan_id);
753 LITTLE_ENDIAN_16(&qlge->nic_config.last_entry);
754 LITTLE_ENDIAN_16(&qlge->nic_config.subsys_vendor_id);
755 LITTLE_ENDIAN_16(&qlge->nic_config.subsys_device_id);
756
757 QL_PRINT(DBG_FLASH, ("(%d): signature=%xh\n",
758 qlge->instance, qlge->nic_config.signature));
759 QL_PRINT(DBG_FLASH, ("(%d): size=%xh\n",
760 qlge->instance, qlge->nic_config.size));
761 QL_PRINT(DBG_FLASH, ("(%d): checksum=%xh\n",
762 qlge->instance, qlge->nic_config.checksum));
763 QL_PRINT(DBG_FLASH, ("(%d): version=%xh\n",
764 qlge->instance, qlge->nic_config.version));
765 QL_PRINT(DBG_FLASH, ("(%d): total_data_size=%xh\n",
766 qlge->instance, qlge->nic_config.total_data_size));
767 QL_PRINT(DBG_FLASH, ("(%d): num_of_entries=%xh\n",
768 qlge->instance, qlge->nic_config.num_of_entries));
769 QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
770 qlge->instance, qlge->nic_config.factory_data_type));
771 QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
772 qlge->instance, qlge->nic_config.factory_data_type_size));
773 QL_PRINT(DBG_FLASH,
774 ("(%d): factory mac=%02x %02x %02x %02x %02x %02x h\n",
775 qlge->instance,
776 qlge->nic_config.factory_MAC[0],
777 qlge->nic_config.factory_MAC[1],
778 qlge->nic_config.factory_MAC[2],
779 qlge->nic_config.factory_MAC[3],
780 qlge->nic_config.factory_MAC[4],
781 qlge->nic_config.factory_MAC[5]));
782
783 QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
784 qlge->instance, qlge->nic_config.clp_data_type));
785 QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
786 qlge->instance, qlge->nic_config.clp_data_type_size));
787 QL_PRINT(DBG_FLASH, ("(%d): clp mac=%x %x %x %x %x %x h\n",
788 qlge->instance,
789 qlge->nic_config.clp_MAC[0],
790 qlge->nic_config.clp_MAC[1],
791 qlge->nic_config.clp_MAC[2],
792 qlge->nic_config.clp_MAC[3],
793 qlge->nic_config.clp_MAC[4],
794 qlge->nic_config.clp_MAC[5]));
795
796 QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
797 qlge->instance, qlge->nic_config.clp_vlan_data_type));
798 QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
799 qlge->instance, qlge->nic_config.clp_vlan_data_type_size));
800 QL_PRINT(DBG_FLASH, ("(%d): vlan_id=%xh\n",
801 qlge->instance, qlge->nic_config.vlan_id));
802
803 QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
804 qlge->instance, qlge->nic_config.last_data_type));
805 QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
806 qlge->instance, qlge->nic_config.last_data_type_size));
807 QL_PRINT(DBG_FLASH, ("(%d): last_entry=%xh\n",
808 qlge->instance, qlge->nic_config.last_entry));
809
810 QL_PRINT(DBG_FLASH, ("(%d): subsys_vendor_id=%xh\n",
811 qlge->instance, qlge->nic_config.subsys_vendor_id));
812 QL_PRINT(DBG_FLASH, ("(%d): subsys_device_id=%xh\n",
813 qlge->instance, qlge->nic_config.subsys_device_id));
814
815 if (chksum != 0 || qlge->nic_config.signature !=
816 FLASH_NIC_CONFIG_SIGNATURE || qlge->nic_config.version != 1) {
817 cmn_err(CE_WARN,
818 "invalid flash nic configuration table: chksum %x, "
819 "signature %x, version %x",
820 chksum, qlge->nic_config.signature,
821 qlge->nic_config.version);
822 return (DDI_FAILURE);
823 }
824
825 return (DDI_SUCCESS);
826 }
827
828 int
829 ql_flash_vpd(qlge_t *qlge, uint8_t *buf)
830 {
831 uint32_t cnt;
832 uint16_t chksum, *bp, data;
833 int rval;
834 uint32_t vpd_size;
835
836 if (buf == NULL) {
837 cmn_err(CE_WARN, "%s(%d) buffer is not available.",
838 __func__, qlge->instance);
839 return (DDI_FAILURE);
840 }
841
842 if (!qlge->flash_vpd_addr) {
843 if (qlge->func_number == qlge->fn0_net)
844 qlge->flash_vpd_addr = ISP_8100_VPD0_ADDR;
845 else
846 qlge->flash_vpd_addr = ISP_8100_VPD1_ADDR;
847 vpd_size = ISP_8100_VPD0_SIZE;
848 }
849 rval = qlge_dump_fcode(qlge, buf, vpd_size, qlge->flash_vpd_addr);
850
851 if (rval != DDI_SUCCESS) {
852 cmn_err(CE_WARN, "%s(%d)read error",
853 __func__, qlge->instance);
854 bzero(buf, vpd_size);
855 return (rval);
856 }
857
858 QL_DUMP(DBG_FLASH, "flash vpd table raw data:\n", buf, 8, vpd_size);
859
860 chksum = 0;
861 data = 0;
862 bp = (uint16_t *)(void *)buf;
863 for (cnt = 0; cnt < (vpd_size/2); cnt++) {
864 data = *bp;
865 LITTLE_ENDIAN_16(&data);
866 chksum += data;
867 bp++;
868 }
869 if (chksum != 0) {
870 cmn_err(CE_WARN, "%s(%d) invalid flash vpd table",
871 __func__, qlge->instance);
872 return (DDI_FAILURE);
873 }
874 return (DDI_SUCCESS);
875 }
876
877 int
878 ql_get_flash_params(qlge_t *qlge)
879 {
880 int rval = DDI_SUCCESS;
881
882 /* Get semaphore to access Flash Address and Flash Data Registers */
883 if (ql_sem_spinlock(qlge, QL_FLASH_SEM_MASK)) {
884 rval = DDI_FAILURE;
885 goto out;
886 }
887 /* do test read of flash ID */
888 rval = ql_flash_id(qlge);
889 if (rval != DDI_SUCCESS)
890 goto out;
891
892 /*
893 * Temporarily set the fdesc.flash_size to
894 * 4M flash size to avoid failing of ql_dump_focde.
895 */
896 qlge->fdesc.flash_size = 4096 * 1024; /* ie. 4M bytes */
897
898 /* Default flash descriptor table. */
899 qlge->fdesc.write_statusreg_cmd = 1;
900 qlge->fdesc.write_enable_bits = 0;
901 qlge->fdesc.unprotect_sector_cmd = 0;
902 qlge->fdesc.protect_sector_cmd = 0;
903 qlge->fdesc.write_disable_bits = 0x9c;
904 qlge->fdesc.block_size = 0x10000;
905 qlge->fdesc.erase_cmd = 0xd8;
906
907 /* ! todo : should read from fltds! */
908 /* !ql_get_flash_params(qlge); */
909 qlge->fltds.flt_addr_hi = 0x36;
910 qlge->fltds.flt_addr_lo = 0x1000;
911 /* read all other tables from Flash memory */
912 if (ql_flash_flt(qlge) != DDI_SUCCESS) {
913 if (CFG_IST(qlge, CFG_CHIP_8100)) {
914 qlge->flash_fdt_addr = ISP_8100_FDT_ADDR; /* 0x360000 */
915 if (qlge->func_number == qlge->fn0_net)
916 /* 0x140200 */
917 qlge->flash_nic_config_table_addr =
918 ISP_8100_NIC_PARAM0_ADDR;
919 else
920 /* 0x140600 */
921 qlge->flash_nic_config_table_addr =
922 ISP_8100_NIC_PARAM1_ADDR;
923 }
924 }
925 (void) ql_flash_desc(qlge);
926 (void) ql_flash_nic_config(qlge);
927
928 out:
929 ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
930
931 return (rval);
932 }
933
934 /*
935 * ql_setup_flash
936 * Gets the manufacturer and id number of the flash chip,
937 * and sets up the size parameter.
938 */
939 int
940 ql_setup_flash(qlge_t *qlge)
941 {
942 int rval = DDI_SUCCESS;
943
944 if (qlge->flash_fltds_addr != 0) {
945 return (rval);
946 }
947 if (ql_sem_spinlock(qlge, QL_FLASH_SEM_MASK)) {
948 rval = DDI_FAILURE;
949 goto out;
950 }
951 /* try reading flash ID */
952 rval = ql_flash_id(qlge);
953 if (rval != DDI_SUCCESS)
954 goto out;
955
956 /* Default flash descriptor table. */
957 qlge->fdesc.write_statusreg_cmd = 1;
958 qlge->fdesc.write_enable_bits = 0;
959 qlge->fdesc.unprotect_sector_cmd = 0;
960 qlge->fdesc.protect_sector_cmd = 0;
961 qlge->fdesc.write_disable_bits = 0x9c;
962 qlge->fdesc.block_size = 0x10000;
963 qlge->fdesc.erase_cmd = 0xd8;
964 /* 1 Get the location of Flash Layout Table Data Structure (FLTDS) */
965 if (ql_find_flash_layout_table_data_structure_addr(qlge)
966 == DDI_SUCCESS) {
967 /* 2,read fltds */
968 if (ql_flash_fltds(qlge) == DDI_SUCCESS) {
969 /*
970 * 3,search for flash descriptor table (FDT)
971 * and Nic Configuration Table indices
972 */
973 if ((qlge->flash_fdt_addr == 0) ||
974 (qlge->flash_nic_config_table_addr == 0)) {
975 rval = ql_flash_flt(qlge);
976 if (rval == DDI_SUCCESS) {
977 (void) ql_flash_desc(qlge);
978 (void) ql_flash_nic_config(qlge);
979 } else {
980 rval = DDI_FAILURE;
981 goto out;
982 }
983 }
984 } else {
985 rval = DDI_FAILURE;
986 goto out;
987 }
988 } else {
989 rval = DDI_FAILURE;
990 goto out;
991 }
992 out:
993 ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
994
995 return (rval);
996
997 }
998
999 /*
1000 * ql_change_endian
1001 * Change endianess of byte array.
1002 */
1003 void
1004 ql_change_endian(uint8_t buf[], size_t size)
1005 {
1006 uint8_t byte;
1007 size_t cnt1;
1008 size_t cnt;
1009
1010 cnt1 = size - 1;
1011 for (cnt = 0; cnt < size / 2; cnt++) {
1012 byte = buf[cnt1];
1013 buf[cnt1] = buf[cnt];
1014 buf[cnt] = byte;
1015 cnt1--;
1016 }
1017 }
1018
1019 static int
1020 ql_wait_flash_reg_ready(qlge_t *qlge, uint32_t wait_bit)
1021 {
1022 uint32_t reg_status;
1023 int rtn_val = DDI_SUCCESS;
1024 uint32_t delay = 300000;
1025
1026 do {
1027 reg_status = ql_read_reg(qlge, REG_FLASH_ADDRESS);
1028 if (reg_status & FLASH_ERR_FLAG) {
1029 cmn_err(CE_WARN,
1030 "%s(%d) flash address register error bit set!",
1031 __func__, qlge->instance);
1032 rtn_val = DDI_FAILURE;
1033 break;
1034 }
1035 if (reg_status & wait_bit) {
1036 break;
1037 }
1038 drv_usecwait(10);
1039 } while (--delay);
1040
1041 if (delay == 0) {
1042 cmn_err(CE_WARN,
1043 "%s(%d) timeout error!", __func__, qlge->instance);
1044 if (qlge->fm_enable) {
1045 ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
1046 atomic_or_32(&qlge->flags, ADAPTER_ERROR);
1047 ddi_fm_service_impact(qlge->dip, DDI_SERVICE_LOST);
1048 }
1049 rtn_val = DDI_FAILURE;
1050 }
1051 return (rtn_val);
1052 }
1053
1054 /*
1055 * ql_read_flash
1056 * Reads a 32bit word from FLASH.
1057 */
1058 static int
1059 ql_read_flash(qlge_t *qlge, uint32_t faddr, uint32_t *bp)
1060 {
1061 int rval = DDI_SUCCESS;
1062
1063 ql_write_reg(qlge, REG_FLASH_ADDRESS, faddr | FLASH_R_FLAG);
1064
1065 /* Wait for READ cycle to complete. */
1066 rval = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG);
1067
1068 if (rval == DDI_SUCCESS) {
1069 *bp = ql_read_reg(qlge, REG_FLASH_DATA);
1070 }
1071 return (rval);
1072 }
1073
1074 static int
1075 ql_read_flash_status(qlge_t *qlge, uint8_t *value)
1076 {
1077 int rtn_val = DDI_SUCCESS;
1078 uint32_t data, cmd = FLASH_CONF_ADDR | FLASH_R_FLAG;
1079
1080 if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1081 != DDI_SUCCESS) {
1082 return (rtn_val);
1083 }
1084 cmd |= FLASH_RDSR_CMD /* 0x05 */;
1085 ql_write_reg(qlge, REG_FLASH_ADDRESS, cmd);
1086 if ((rtn_val = ql_wait_flash_reg_ready(qlge,
1087 FLASH_RDY_FLAG | FLASH_R_FLAG)) != DDI_SUCCESS) {
1088 return (rtn_val);
1089 }
1090 data = ql_read_reg(qlge, REG_FLASH_DATA);
1091 *value = (uint8_t)(data & 0xff);
1092 return (rtn_val);
1093 }
1094
1095 static int
1096 ql_flash_write_enable(qlge_t *qlge)
1097 {
1098 uint8_t reg_status;
1099 int rtn_val = DDI_SUCCESS;
1100 uint32_t cmd = FLASH_CONF_ADDR;
1101 uint32_t delay = 300000;
1102
1103 if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1104 != DDI_SUCCESS) {
1105 cmn_err(CE_WARN,
1106 "%s(%d) timeout!", __func__, qlge->instance);
1107 rtn_val = DDI_FAILURE;
1108 return (rtn_val);
1109 }
1110 cmd |= qlge->fdesc.write_enable_cmd;
1111 ql_write_reg(qlge, REG_FLASH_ADDRESS, cmd);
1112 /* wait for WEL bit set */
1113 if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1114 == DDI_SUCCESS) {
1115 do {
1116 (void) ql_read_flash_status(qlge, ®_status);
1117 if (reg_status & BIT_1)
1118 break;
1119 drv_usecwait(10);
1120 } while (--delay);
1121 }
1122 if (delay == 0) {
1123 cmn_err(CE_WARN,
1124 "%s(%d) timeout error! flash status reg: %x",
1125 __func__, qlge->instance, reg_status);
1126 rtn_val = DDI_FAILURE;
1127 }
1128 return (rtn_val);
1129 }
1130
1131 static int
1132 ql_flash_erase_sector(qlge_t *qlge, uint32_t sectorAddr)
1133 {
1134 int rtn_val = DDI_SUCCESS;
1135 uint32_t data, cmd = FLASH_CONF_ADDR;
1136 uint32_t delay = 300000;
1137 uint8_t flash_status;
1138
1139 if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1140 != DDI_SUCCESS) {
1141 return (rtn_val);
1142 }
1143
1144 cmd |= (0x0300 | qlge->fdesc.erase_cmd);
1145 data = ((sectorAddr & 0xff) << 16) | (sectorAddr & 0xff00) |
1146 ((sectorAddr & 0xff0000) >> 16);
1147
1148 ql_write_reg(qlge, REG_FLASH_DATA, data);
1149 ql_write_reg(qlge, REG_FLASH_ADDRESS, cmd);
1150
1151 if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1152 == DDI_SUCCESS) {
1153 /* wait Write In Progress (WIP) bit to reset */
1154 do {
1155 (void) ql_read_flash_status(qlge, &flash_status);
1156 if ((flash_status & BIT_0 /* WIP */) == 0)
1157 break;
1158 drv_usecwait(10);
1159 } while (--delay);
1160 } else {
1161 return (rtn_val);
1162 }
1163
1164 if (delay == 0) {
1165 cmn_err(CE_WARN,
1166 "%s(%d) timeout error! flash status reg: %x",
1167 __func__, qlge->instance, flash_status);
1168 rtn_val = DDI_FAILURE;
1169 }
1170 return (rtn_val);
1171 }
1172
1173 /*
1174 * ql_write_flash
1175 * Writes a 32bit word to FLASH.
1176 */
1177 static int
1178 ql_write_flash(qlge_t *qlge, uint32_t addr, uint32_t data)
1179 {
1180 int rval = DDI_SUCCESS;
1181 uint32_t delay = 300000;
1182 uint8_t flash_status;
1183
1184 ql_write_reg(qlge, REG_FLASH_DATA, data);
1185 (void) ql_read_reg(qlge, REG_FLASH_DATA);
1186 ql_write_reg(qlge, REG_FLASH_ADDRESS, addr);
1187
1188 if ((rval = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1189 == DDI_SUCCESS) {
1190 if ((addr & FLASH_ADDR_MASK) == FLASH_CONF_ADDR) {
1191 /* wait Write In Progress (WIP) bit to reset */
1192 do {
1193 (void) ql_read_flash_status(qlge,
1194 &flash_status);
1195 if ((flash_status & BIT_0 /* WIP */) == 0)
1196 break;
1197 drv_usecwait(10);
1198 } while (--delay);
1199 }
1200 } else {
1201 return (rval);
1202 }
1203
1204 if (delay == 0) {
1205 cmn_err(CE_WARN,
1206 "%s(%d) timeout error! flash status reg: %x",
1207 __func__, qlge->instance, flash_status);
1208 rval = DDI_FAILURE;
1209 }
1210
1211 return (rval);
1212 }
1213
1214 /*
1215 * ql_unprotect_flash
1216 * Enable writes
1217 */
1218 static int
1219 ql_unprotect_flash(qlge_t *qlge)
1220 {
1221 int fdata, rtn_val;
1222
1223 if ((rtn_val = ql_flash_write_enable(qlge)) != DDI_SUCCESS) {
1224 return (rtn_val);
1225 }
1226
1227 if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1228 != DDI_SUCCESS) {
1229 return (rtn_val);
1230 }
1231
1232 /*
1233 * Remove block write protection (SST and ST) and
1234 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
1235 * Unprotect sectors.
1236 */
1237 (void) ql_write_flash(qlge,
1238 FLASH_CONF_ADDR | 0x100 | qlge->fdesc.write_statusreg_cmd,
1239 qlge->fdesc.write_enable_bits);
1240
1241 if (qlge->fdesc.unprotect_sector_cmd != 0) {
1242 for (fdata = 0; fdata < 0x10; fdata++) {
1243 (void) ql_write_flash(qlge, FLASH_CONF_ADDR |
1244 0x300 | qlge->fdesc.unprotect_sector_cmd, fdata);
1245 }
1246
1247 (void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x300 |
1248 qlge->fdesc.unprotect_sector_cmd, 0x00400f);
1249 (void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x300 |
1250 qlge->fdesc.unprotect_sector_cmd, 0x00600f);
1251 (void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x300 |
1252 qlge->fdesc.unprotect_sector_cmd, 0x00800f);
1253 }
1254 rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG);
1255 return (rtn_val);
1256 }
1257
1258 /*
1259 * ql_protect_flash
1260 * Disable writes
1261 */
1262 static int
1263 ql_protect_flash(qlge_t *qlge)
1264 {
1265 int fdata, rtn_val;
1266
1267 if ((rtn_val = ql_flash_write_enable(qlge)) != DDI_SUCCESS) {
1268 return (rtn_val);
1269 }
1270
1271 if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1272 != DDI_SUCCESS) {
1273 return (rtn_val);
1274 }
1275 /*
1276 * Protect sectors.
1277 * Set block write protection (SST and ST) and
1278 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
1279 */
1280
1281 if (qlge->fdesc.protect_sector_cmd != 0) {
1282 for (fdata = 0; fdata < 0x10; fdata++) {
1283 (void) ql_write_flash(qlge, FLASH_CONF_ADDR |
1284 0x330 | qlge->fdesc.protect_sector_cmd, fdata);
1285 }
1286 (void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x330 |
1287 qlge->fdesc.protect_sector_cmd, 0x00400f);
1288 (void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x330 |
1289 qlge->fdesc.protect_sector_cmd, 0x00600f);
1290 (void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x330 |
1291 qlge->fdesc.protect_sector_cmd, 0x00800f);
1292
1293 (void) ql_write_flash(qlge,
1294 FLASH_CONF_ADDR | 0x101, 0x80);
1295 } else {
1296 (void) ql_write_flash(qlge,
1297 FLASH_CONF_ADDR | 0x100 | qlge->fdesc.write_statusreg_cmd,
1298 qlge->fdesc.write_disable_bits /* 0x9c */);
1299 }
1300
1301 rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG);
1302 return (rtn_val);
1303 }
1304
1305 /*
1306 * ql_write_flash_test
1307 * test write to a flash sector that is not being used
1308 */
1309 void
1310 ql_write_flash_test(qlge_t *qlge, uint32_t test_addr)
1311 {
1312 uint32_t old_data, data;
1313 uint32_t addr = 0;
1314
1315 addr = (test_addr / 4);
1316 (void) ql_read_flash(qlge, addr, &old_data);
1317 QL_PRINT(DBG_FLASH, ("read addr %x old value %x\n", test_addr,
1318 old_data));
1319
1320 /* enable writing to flash */
1321 (void) ql_unprotect_flash(qlge);
1322
1323 /* erase the sector */
1324 (void) ql_flash_erase_sector(qlge, test_addr);
1325 (void) ql_read_flash(qlge, addr, &data);
1326 QL_PRINT(DBG_FLASH, ("after sector erase, addr %x value %x\n",
1327 test_addr, data));
1328
1329 /* write new value to it and read back to confirm */
1330 data = 0x33445566;
1331 (void) ql_write_flash(qlge, addr, data);
1332 QL_PRINT(DBG_FLASH, ("new value written to addr %x value %x\n",
1333 test_addr, data));
1334 (void) ql_read_flash(qlge, addr, &data);
1335 if (data != 0x33445566) {
1336 cmn_err(CE_WARN, "flash write test failed, get data %x"
1337 " after writing", data);
1338 }
1339
1340 /* write old value to it and read back to restore */
1341 (void) ql_flash_erase_sector(qlge, test_addr);
1342 (void) ql_write_flash(qlge, addr, old_data);
1343 (void) ql_read_flash(qlge, addr, &data);
1344 QL_PRINT(DBG_FLASH, ("write back old value addr %x value %x\n",
1345 test_addr, data));
1346
1347 /* test done, protect the flash to forbid any more flash writting */
1348 (void) ql_protect_flash(qlge);
1349
1350 }
1351
1352
1353 void
1354 ql_write_flash_test2(qlge_t *qlge, uint32_t test_addr)
1355 {
1356 uint32_t data, old_data;
1357
1358 (void) qlge_dump_fcode(qlge, (uint8_t *)&old_data, sizeof (old_data),
1359 test_addr);
1360 QL_PRINT(DBG_FLASH, ("read addr %x old value %x\n",
1361 test_addr, old_data));
1362
1363 data = 0x12345678;
1364
1365 QL_PRINT(DBG_FLASH, ("write new test value %x\n", data));
1366 (void) qlge_load_flash(qlge, (uint8_t *)&data, sizeof (data),
1367 test_addr);
1368 (void) qlge_dump_fcode(qlge, (uint8_t *)&data, sizeof (data),
1369 test_addr);
1370 if (data != 0x12345678) {
1371 cmn_err(CE_WARN,
1372 "flash write test failed, get data %x after writing",
1373 data);
1374 }
1375 /* write old value to it and read back to restore */
1376 (void) qlge_load_flash(qlge, (uint8_t *)&old_data, sizeof (old_data),
1377 test_addr);
1378 (void) qlge_dump_fcode(qlge, (uint8_t *)&data, sizeof (data),
1379 test_addr);
1380 QL_PRINT(DBG_FLASH, ("write back old value addr %x value %x verified\n",
1381 test_addr, data));
1382 }
1383
1384 /*
1385 * ql_sem_flash_lock
1386 * Flash memory is a shared resource amoung various PCI Functions, so,
1387 * anyone wants to access flash memory, it needs to lock it first.
1388 */
1389 int
1390 ql_sem_flash_lock(qlge_t *qlge)
1391 {
1392 int rval = DDI_SUCCESS;
1393
1394 /* Get semaphore to access Flash Address and Flash Data Registers */
1395 if (ql_sem_spinlock(qlge, QL_FLASH_SEM_MASK)) {
1396 rval = DDI_FAILURE;
1397 }
1398 return (rval);
1399 }
1400
1401 void
1402 ql_sem_flash_unlock(qlge_t *qlge)
1403 {
1404 ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
1405 }