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 2009 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 	if (temp == NULL) {
245 		cmn_err(CE_WARN, "%s(%d): Unable to allocate buffer",
246 		    __func__, qlge->instance);
247 		ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
248 		return (DDI_FAILURE);
249 	}
250 
251 	(void) ql_unprotect_flash(qlge);
252 
253 	get_sector_number(qlge, faddr, &start_block);
254 	get_sector_number(qlge, faddr + len - 1, &end_block);
255 
256 	QL_PRINT(DBG_FLASH, ("%s(%d) start_block %x, end_block %x\n",
257 	    __func__, qlge->instance, start_block, end_block));
258 
259 	for (num = start_block; num <= end_block; num++) {
260 		QL_PRINT(DBG_FLASH,
261 		    ("%s(%d) sector_size 0x%x, sector read addr %x\n",
262 		    __func__, qlge->instance, sector_size, num * sector_size));
263 		/* read one whole sector flash data to buffer */
264 		rval = qlge_dump_fcode(qlge, (uint8_t *)temp, sector_size,
265 		    num * sector_size);
266 
267 		start_byte = num * sector_size;
268 		end_byte = start_byte + sector_size -1;
269 		if (start_byte < faddr)
270 			start_byte = faddr;
271 		if (end_byte > (faddr + len))
272 			end_byte = (faddr + len - 1);
273 
274 		addr_src = start_byte - faddr;
275 		addr_desc = start_byte - num * sector_size;
276 		bp = (caddr_t)dp + addr_src;
277 		bdesc = (caddr_t)temp + addr_desc;
278 		bcopy(bp, bdesc, (end_byte - start_byte + 1));
279 
280 		/* write the whole sector data to flash */
281 		if (ql_erase_and_write_to_flash(qlge, temp, sector_size,
282 		    num * sector_size) != DDI_SUCCESS)
283 			goto out;
284 	}
285 	rval = DDI_SUCCESS;
286 out:
287 	(void) ql_protect_flash(qlge);
288 	kmem_free(temp, sector_size);
289 
290 	ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
291 
292 	if (rval != DDI_SUCCESS) {
293 		cmn_err(CE_WARN, "%s(%d failed=%xh",
294 		    __func__, qlge->instance, rval);
295 	}
296 
297 	return (rval);
298 }
299 
300 
301 /*
302  * ql_check_pci
303  * checks the passed buffer for a valid pci signature and
304  * expected (and in range) pci length values.
305  * On successful pci check, nextpos adjusted to next pci header.
306  */
307 static int
308 ql_check_pci(qlge_t *qlge, uint8_t *buf, uint32_t *nextpos)
309 {
310 	pci_header_t *pcih;
311 	pci_data_t *pcid;
312 	uint32_t doff;
313 	uint8_t *pciinfo;
314 	uint32_t image_size = 0;
315 	int rval = CONTINUE_SEARCH;
316 
317 	QL_PRINT(DBG_FLASH, ("%s(%d) check image at 0x%x\n",
318 	    __func__, qlge->instance, *nextpos));
319 
320 	if (buf != NULL) {
321 		pciinfo = buf;
322 	} else {
323 		cmn_err(CE_WARN, "%s(%d) failed, null buf ptr passed",
324 		    __func__, qlge->instance);
325 		return (STOP_SEARCH);
326 	}
327 
328 	/* get the pci header image length */
329 	pcih = (pci_header_t *)pciinfo;
330 
331 	doff = pcih->dataoffset[1];
332 	doff <<= 8;
333 	doff |= pcih->dataoffset[0];
334 
335 	/* some header section sanity check */
336 	if (pcih->signature[0] != PCI_HEADER0 /* '55' */ ||
337 	    pcih->signature[1] != PCI_HEADER1 /* 'AA' */ || doff > 50) {
338 		cmn_err(CE_WARN, "%s(%d) image format error: s0=%xh, s1=%xh,"
339 		    "off=%xh\n", __func__, qlge->instance,
340 		    pcih->signature[0], pcih->signature[1], doff);
341 		return (STOP_SEARCH);
342 	}
343 
344 	pcid = (pci_data_t *)(pciinfo + doff);
345 
346 	/* a slight sanity data section check */
347 	if (pcid->signature[0] != 'P' || pcid->signature[1] != 'C' ||
348 	    pcid->signature[2] != 'I' || pcid->signature[3] != 'R') {
349 		cmn_err(CE_WARN, "%s(%d) failed, data sig mismatch!",
350 		    __func__, qlge->instance);
351 		return (STOP_SEARCH);
352 	}
353 	image_size =
354 	    (pcid->imagelength[0] | (pcid->imagelength[1] << 8))*
355 	    PCI_SECTOR_SIZE /* 512 */;
356 
357 	switch (pcid->codetype) {
358 	case PCI_CODE_X86PC:
359 		QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_BIOS \n",
360 		    __func__, qlge->instance));
361 		break;
362 	case PCI_CODE_FCODE:
363 		QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_FCODE \n",
364 		    __func__, qlge->instance));
365 		break;
366 	case PCI_CODE_EFI:
367 		QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_EFI \n",
368 		    __func__, qlge->instance));
369 		break;
370 	case PCI_CODE_HPPA:
371 		QL_PRINT(DBG_FLASH, ("%s(%d) boot image is PCI_CODE_HPPA \n",
372 		    __func__, qlge->instance));
373 		break;
374 	default:
375 		QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_UNKNOWN \n",
376 		    __func__, qlge->instance));
377 		break;
378 	}
379 
380 	QL_PRINT(DBG_FLASH, ("%s(%d) image size %x at %x\n",
381 	    __func__, qlge->instance, image_size, *nextpos));
382 
383 	if (pcid->indicator == PCI_IND_LAST_IMAGE) {
384 		QL_PRINT(DBG_FLASH, ("%s(%d) last boot image found \n",
385 		    __func__, qlge->instance));
386 		rval = LAST_IMAGE_FOUND;
387 	} else {
388 		rval = CONTINUE_SEARCH;
389 	}
390 	/* Get the next flash image address */
391 	*nextpos += image_size;
392 
393 	return (rval);
394 }
395 
396 /*
397  * ql_find_flash_layout_table_data_structure
398  * Find Flash Layout Table Data Structure (FLTDS) that
399  * is located at the end of last boot image.
400  * Assume FLTDS is located with first 2M bytes.
401  * Note:
402  * Driver must be in stalled state prior to entering or
403  * add code to this function prior to calling ql_setup_flash()
404  */
405 int
406 ql_find_flash_layout_table_data_structure_addr(qlge_t *qlge)
407 {
408 	int rval = DDI_FAILURE;
409 	int result = CONTINUE_SEARCH;
410 	uint32_t freadpos = 0;
411 	uint8_t buf[FBUFSIZE];
412 
413 	if (qlge->flash_fltds_addr != 0) {
414 		QL_PRINT(DBG_FLASH, ("%s(%d) done already\n",
415 		    __func__, qlge->instance));
416 		return (DDI_SUCCESS);
417 	}
418 	/*
419 	 * Temporarily set the fdesc.flash_size to
420 	 * 1M flash size to avoid failing of ql_dump_focde.
421 	 */
422 	qlge->fdesc.flash_size = FLASH_FIRMWARE_IMAGE_ADDR;
423 
424 	while (result == CONTINUE_SEARCH) {
425 
426 		if ((rval = qlge_dump_fcode(qlge, buf, FBUFSIZE, freadpos))
427 		    != DDI_SUCCESS) {
428 			cmn_err(CE_WARN, "%s(%d) qlge_dump_fcode failed"
429 			    " pos=%xh rval=%xh",
430 			    __func__, qlge->instance, freadpos, rval);
431 			break;
432 		}
433 		/*
434 		 * checkout the pci boot image format
435 		 * and get next read address
436 		 */
437 		result = ql_check_pci(qlge, buf, &freadpos);
438 		/*
439 		 * find last image? If so, then the freadpos
440 		 * is the address of FLTDS
441 		 */
442 		if (result == LAST_IMAGE_FOUND) {
443 			QL_PRINT(DBG_FLASH,
444 			    ("%s(%d) flash layout table data structure "
445 			    "(FLTDS) address is at %x \n", __func__,
446 			    qlge->instance, freadpos));
447 			qlge->flash_fltds_addr = freadpos;
448 			rval = DDI_SUCCESS;
449 			break;
450 		} else if (result == STOP_SEARCH) {
451 			cmn_err(CE_WARN, "%s(%d) flash header incorrect,"
452 			    "stop searching",
453 			    __func__, qlge->instance);
454 			break;
455 		}
456 	}
457 	return (rval);
458 }
459 
460 /*
461  * ql_flash_fltds
462  * Get flash layout table data structure table.
463  */
464 static int
465 ql_flash_fltds(qlge_t *qlge)
466 {
467 	uint32_t cnt;
468 	uint16_t chksum, *bp, data;
469 	int rval;
470 
471 	rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->fltds,
472 	    sizeof (ql_fltds_t), qlge->flash_fltds_addr);
473 	if (rval != DDI_SUCCESS) {
474 		cmn_err(CE_WARN, "%s(%d)read error",
475 		    __func__, qlge->instance);
476 		bzero(&qlge->fltds, sizeof (ql_fltds_t));
477 		return (rval);
478 	}
479 
480 	QL_DUMP(DBG_FLASH, "flash layout table data structure:\n",
481 	    &qlge->fltds, 8, sizeof (ql_fltds_t));
482 
483 	chksum = 0;
484 	data = 0;
485 	bp = (uint16_t *)&qlge->fltds;
486 	for (cnt = 0; cnt < (sizeof (ql_fltds_t)) / 2; cnt++) {
487 		data = *bp;
488 		LITTLE_ENDIAN_16(&data);
489 		chksum += data;
490 		bp++;
491 	}
492 
493 	LITTLE_ENDIAN_32(&qlge->fltds.signature);
494 	LITTLE_ENDIAN_16(&qlge->fltds.flt_addr_lo);
495 	LITTLE_ENDIAN_16(&qlge->fltds.flt_addr_hi);
496 	LITTLE_ENDIAN_16(&qlge->fltds.checksum);
497 
498 	QL_PRINT(DBG_FLASH, ("%s(%d) signature %xh\n",
499 	    __func__, qlge->instance, qlge->fltds.signature));
500 	QL_PRINT(DBG_FLASH, ("%s(%d) flt_addr_lo %xh\n",
501 	    __func__, qlge->instance, qlge->fltds.flt_addr_lo));
502 	QL_PRINT(DBG_FLASH, ("%s(%d) flt_addr_hi %xh\n",
503 	    __func__, qlge->instance, qlge->fltds.flt_addr_hi));
504 	QL_PRINT(DBG_FLASH, ("%s(%d) version %xh\n",
505 	    __func__, qlge->instance, qlge->fltds.version));
506 	QL_PRINT(DBG_FLASH, ("%s(%d) checksum %xh\n",
507 	    __func__, qlge->instance, qlge->fltds.checksum));
508 	/* QFLT */
509 	if (chksum != 0 || qlge->fltds.signature != FLASH_FLTDS_SIGNATURE) {
510 		cmn_err(CE_WARN, "%s(%d) invalid flash layout table data"
511 		    " structure", __func__, qlge->instance);
512 		bzero(&qlge->fltds, sizeof (ql_fltds_t));
513 		return (DDI_FAILURE);
514 	}
515 	return (DDI_SUCCESS);
516 }
517 
518 /*
519  * ql_flash_flt
520  * Get flash layout table.
521  */
522 int
523 ql_flash_flt(qlge_t *qlge)
524 {
525 	uint32_t addr, cnt;
526 	int rval = DDI_FAILURE;
527 	ql_flt_entry_t *entry;
528 	uint8_t region;
529 
530 	addr = qlge->fltds.flt_addr_hi;
531 	addr <<= 16;
532 	addr |= qlge->fltds.flt_addr_lo;
533 
534 	/* first read flt header to know how long the table is */
535 	rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->flt.header,
536 	    sizeof (ql_flt_header_t), addr);
537 	if (rval != DDI_SUCCESS) {
538 		cmn_err(CE_WARN, "%s(%d) read flt header at %x error",
539 		    __func__, qlge->instance, addr);
540 		bzero(&qlge->flt, sizeof (ql_flt_header_t));
541 		return (rval);
542 	}
543 
544 	LITTLE_ENDIAN_16(&qlge->flt.header.version);
545 	LITTLE_ENDIAN_16(&qlge->flt.header.length);
546 	LITTLE_ENDIAN_16(&qlge->flt.header.checksum);
547 	LITTLE_ENDIAN_16(&qlge->flt.header.reserved);
548 
549 	if ((qlge->flt.header.version != 1) &&
550 	    (qlge->flt.header.version != 0)) {
551 		cmn_err(CE_WARN, "%s(%d) read flt header at %x error",
552 		    __func__, qlge->instance, addr);
553 		bzero(&qlge->flt, sizeof (ql_flt_header_t));
554 		return (DDI_FAILURE);
555 	}
556 	/* 2.allocate memory to save all flt table entries */
557 	if ((qlge->flt.ql_flt_entry_ptr = (ql_flt_entry_t *)
558 	    (kmem_zalloc(qlge->flt.header.length, KM_SLEEP))) == NULL) {
559 		cmn_err(CE_WARN, "%s(%d) flt table alloc failed",
560 		    __func__, qlge->instance);
561 		goto err;
562 	}
563 	/* how many tables? */
564 	qlge->flt.num_entries = (uint16_t)(qlge->flt.header.length /
565 	    sizeof (ql_flt_entry_t));
566 
567 	/* 3. read the rest of flt table */
568 	addr += (uint32_t)sizeof (ql_flt_header_t);
569 	QL_PRINT(DBG_FLASH, ("%s(%d) flt has %x entries \n",
570 	    __func__, qlge->instance, qlge->flt.num_entries));
571 	rval = qlge_dump_fcode(qlge,
572 	    (uint8_t *)qlge->flt.ql_flt_entry_ptr, qlge->flt.header.length,
573 	    addr);
574 	if (rval != DDI_SUCCESS) {
575 		cmn_err(CE_WARN, "read flt table entry error");
576 		goto err;
577 	}
578 
579 	entry = (ql_flt_entry_t *)qlge->flt.ql_flt_entry_ptr;
580 	for (cnt = 0; cnt < qlge->flt.num_entries; cnt++) {
581 		LITTLE_ENDIAN_32(&entry->size);
582 		LITTLE_ENDIAN_32(&entry->begin_addr);
583 		LITTLE_ENDIAN_32(&entry->end_addr);
584 		entry++;
585 	}
586 	/* TO Do :4. Checksum verification */
587 
588 	/* 5.search index of Flash Descriptor Table in the Flash Layout Table */
589 	entry = (ql_flt_entry_t *)qlge->flt.ql_flt_entry_ptr;
590 	qlge->flash_fdt_addr = 0;
591 	for (cnt = 0; cnt < qlge->flt.num_entries; cnt++) {
592 		if (entry->region == FLT_REGION_FDT) {
593 			qlge->flash_flt_fdt_index = cnt;
594 			qlge->flash_fdt_addr = entry->begin_addr;
595 			qlge->flash_fdt_size = entry->size;
596 			QL_PRINT(DBG_FLASH, ("%s(%d) flash_flt_fdt_index is"
597 			    " %x, addr %x,size %x \n", __func__,
598 			    qlge->instance,
599 			    cnt, entry->begin_addr, entry->size));
600 			break;
601 		}
602 		entry++;
603 	}
604 
605 	if (qlge->flash_fdt_addr == 0) {
606 		cmn_err(CE_WARN, "%s(%d) flash descriptor table not found",
607 		    __func__, qlge->instance);
608 		goto err;
609 	}
610 	/* 6.search index of Nic Config. Table in the Flash Layout Table */
611 	entry = (ql_flt_entry_t *)qlge->flt.ql_flt_entry_ptr;
612 	if (qlge->func_number == qlge->fn0_net)
613 		region = FLT_REGION_NIC_PARAM0;
614 	else
615 		region = FLT_REGION_NIC_PARAM1;
616 	qlge->flash_nic_config_table_addr = 0;
617 	for (cnt = 0; cnt < qlge->flt.num_entries; cnt++) {
618 		if (entry->region == region) {
619 			qlge->flash_flt_nic_config_table_index = cnt;
620 			qlge->flash_nic_config_table_addr = entry->begin_addr;
621 			qlge->flash_nic_config_table_size = entry->size;
622 			QL_PRINT(DBG_FLASH, ("%s(%d) "
623 			    "flash_flt_nic_config_table_index "
624 			    "is %x, address %x, size %x \n",
625 			    __func__, qlge->instance,
626 			    cnt, entry->begin_addr, entry->size));
627 			break;
628 		}
629 		entry++;
630 	}
631 	if (qlge->flash_nic_config_table_addr == 0) {
632 		cmn_err(CE_WARN, "%s(%d) NIC Configuration Table not found",
633 		    __func__, qlge->instance);
634 		goto err;
635 	}
636 
637 	return (DDI_SUCCESS);
638 err:
639 	bzero(&qlge->flt, sizeof (ql_flt_header_t));
640 	if (qlge->flt.ql_flt_entry_ptr != NULL) {
641 		bzero(&qlge->flt.ql_flt_entry_ptr, qlge->flt.header.length);
642 		kmem_free(qlge->flt.ql_flt_entry_ptr, qlge->flt.header.length);
643 		qlge->flt.ql_flt_entry_ptr = NULL;
644 	}
645 	cmn_err(CE_WARN, "%s(%d) read FLT failed", __func__, qlge->instance);
646 	return (DDI_FAILURE);
647 }
648 
649 /*
650  * ql_flash_desc
651  * Get flash descriptor table.
652  */
653 static int
654 ql_flash_desc(qlge_t *qlge)
655 {
656 	uint8_t w8;
657 	uint32_t cnt, addr;
658 	uint16_t chksum, *bp, data;
659 	int rval;
660 
661 	addr = qlge->flash_fdt_addr;
662 
663 	rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->fdesc,
664 	    sizeof (flash_desc_t), addr);
665 	if (rval != DDI_SUCCESS) {
666 		cmn_err(CE_WARN, "%s(%d) read Flash Descriptor Table error",
667 		    __func__, qlge->instance);
668 		bzero(&qlge->fdesc, sizeof (flash_desc_t));
669 		return (rval);
670 	}
671 
672 	chksum = 0;
673 	data = 0;
674 	bp = (uint16_t *)&qlge->fdesc;
675 	for (cnt = 0; cnt < (sizeof (flash_desc_t)) / 2; cnt++) {
676 		data = *bp;
677 		LITTLE_ENDIAN_16(&data);
678 		chksum += data;
679 		bp++;
680 	}
681 	/* endian adjustment */
682 	LITTLE_ENDIAN_32(&qlge->fdesc.flash_valid);
683 	LITTLE_ENDIAN_16(&qlge->fdesc.flash_version);
684 	LITTLE_ENDIAN_16(&qlge->fdesc.flash_len);
685 	LITTLE_ENDIAN_16(&qlge->fdesc.flash_checksum);
686 	LITTLE_ENDIAN_16(&qlge->fdesc.flash_unused);
687 	LITTLE_ENDIAN_16(&qlge->fdesc.flash_manuf);
688 	LITTLE_ENDIAN_16(&qlge->fdesc.flash_id);
689 	LITTLE_ENDIAN_32(&qlge->fdesc.block_size);
690 	LITTLE_ENDIAN_32(&qlge->fdesc.alt_block_size);
691 	LITTLE_ENDIAN_32(&qlge->fdesc.flash_size);
692 	LITTLE_ENDIAN_32(&qlge->fdesc.write_enable_data);
693 	LITTLE_ENDIAN_32(&qlge->fdesc.read_timeout);
694 
695 	/* flash size in desc table is in 1024 bytes */
696 	QL_PRINT(DBG_FLASH, ("flash_valid=%xh\n", qlge->fdesc.flash_valid));
697 	QL_PRINT(DBG_FLASH, ("flash_version=%xh\n", qlge->fdesc.flash_version));
698 	QL_PRINT(DBG_FLASH, ("flash_len=%xh\n", qlge->fdesc.flash_len));
699 	QL_PRINT(DBG_FLASH, ("flash_checksum=%xh\n",
700 	    qlge->fdesc.flash_checksum));
701 
702 	w8 = qlge->fdesc.flash_model[15];
703 	qlge->fdesc.flash_model[15] = 0;
704 	QL_PRINT(DBG_FLASH, ("flash_model=%s\n", qlge->fdesc.flash_model));
705 	qlge->fdesc.flash_model[15] = w8;
706 	QL_PRINT(DBG_FLASH, ("flash_size=%xK bytes\n", qlge->fdesc.flash_size));
707 	qlge->fdesc.flash_size = qlge->fdesc.flash_size * 0x400;
708 	qlge->flash_info.flash_size = qlge->fdesc.flash_size;
709 
710 	if (chksum != 0 || qlge->fdesc.flash_valid != FLASH_DESC_VAILD ||
711 	    qlge->fdesc.flash_version != FLASH_DESC_VERSION) {
712 		cmn_err(CE_WARN, "invalid descriptor table");
713 		bzero(&qlge->fdesc, sizeof (flash_desc_t));
714 		return (DDI_FAILURE);
715 	}
716 
717 	return (DDI_SUCCESS);
718 }
719 
720 /*
721  * ql_flash_nic_config
722  * Get flash NIC Configuration table.
723  */
724 static int
725 ql_flash_nic_config(qlge_t *qlge)
726 {
727 	uint32_t cnt, addr;
728 	uint16_t chksum, *bp, data;
729 	int rval;
730 
731 	addr = qlge->flash_nic_config_table_addr;
732 
733 	rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->nic_config,
734 	    sizeof (ql_nic_config_t), addr);
735 
736 	if (rval != DDI_SUCCESS) {
737 		cmn_err(CE_WARN, "fail to read nic_cfg image %xh", rval);
738 		bzero(&qlge->nic_config, sizeof (ql_nic_config_t));
739 		return (rval);
740 	}
741 
742 	chksum = 0;
743 	data = 0;
744 	bp = (uint16_t *)&qlge->nic_config;
745 	for (cnt = 0; cnt < (sizeof (ql_nic_config_t)) / 2; cnt++) {
746 		data = *bp;
747 		LITTLE_ENDIAN_16(&data);
748 		chksum += data;
749 		bp++;
750 	}
751 
752 	LITTLE_ENDIAN_32(&qlge->nic_config.signature);
753 	LITTLE_ENDIAN_16(&qlge->nic_config.version);
754 	LITTLE_ENDIAN_16(&qlge->nic_config.size);
755 	LITTLE_ENDIAN_16(&qlge->nic_config.checksum);
756 	LITTLE_ENDIAN_16(&qlge->nic_config.total_data_size);
757 	LITTLE_ENDIAN_16(&qlge->nic_config.num_of_entries);
758 	LITTLE_ENDIAN_16(&qlge->nic_config.vlan_id);
759 	LITTLE_ENDIAN_16(&qlge->nic_config.last_entry);
760 	LITTLE_ENDIAN_16(&qlge->nic_config.subsys_vendor_id);
761 	LITTLE_ENDIAN_16(&qlge->nic_config.subsys_device_id);
762 
763 	QL_PRINT(DBG_FLASH, ("(%d): signature=%xh\n",
764 	    qlge->instance, qlge->nic_config.signature));
765 	QL_PRINT(DBG_FLASH, ("(%d): size=%xh\n",
766 	    qlge->instance, qlge->nic_config.size));
767 	QL_PRINT(DBG_FLASH, ("(%d): checksum=%xh\n",
768 	    qlge->instance, qlge->nic_config.checksum));
769 	QL_PRINT(DBG_FLASH, ("(%d): version=%xh\n",
770 	    qlge->instance, qlge->nic_config.version));
771 	QL_PRINT(DBG_FLASH, ("(%d): total_data_size=%xh\n",
772 	    qlge->instance, qlge->nic_config.total_data_size));
773 	QL_PRINT(DBG_FLASH, ("(%d): num_of_entries=%xh\n",
774 	    qlge->instance, qlge->nic_config.num_of_entries));
775 	QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
776 	    qlge->instance, qlge->nic_config.factory_data_type));
777 	QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
778 	    qlge->instance, qlge->nic_config.factory_data_type_size));
779 	QL_PRINT(DBG_FLASH,
780 	    ("(%d): factory mac=%02x %02x %02x %02x %02x %02x h\n",
781 	    qlge->instance,
782 	    qlge->nic_config.factory_MAC[0],
783 	    qlge->nic_config.factory_MAC[1],
784 	    qlge->nic_config.factory_MAC[2],
785 	    qlge->nic_config.factory_MAC[3],
786 	    qlge->nic_config.factory_MAC[4],
787 	    qlge->nic_config.factory_MAC[5]));
788 
789 	QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
790 	    qlge->instance, qlge->nic_config.clp_data_type));
791 	QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
792 	    qlge->instance, qlge->nic_config.clp_data_type_size));
793 	QL_PRINT(DBG_FLASH, ("(%d): clp mac=%x %x %x %x %x %x h\n",
794 	    qlge->instance,
795 	    qlge->nic_config.clp_MAC[0],
796 	    qlge->nic_config.clp_MAC[1],
797 	    qlge->nic_config.clp_MAC[2],
798 	    qlge->nic_config.clp_MAC[3],
799 	    qlge->nic_config.clp_MAC[4],
800 	    qlge->nic_config.clp_MAC[5]));
801 
802 	QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
803 	    qlge->instance, qlge->nic_config.clp_vlan_data_type));
804 	QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
805 	    qlge->instance, qlge->nic_config.clp_vlan_data_type_size));
806 	QL_PRINT(DBG_FLASH, ("(%d): vlan_id=%xh\n",
807 	    qlge->instance, qlge->nic_config.vlan_id));
808 
809 	QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
810 	    qlge->instance, qlge->nic_config.last_data_type));
811 	QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
812 	    qlge->instance, qlge->nic_config.last_data_type_size));
813 	QL_PRINT(DBG_FLASH, ("(%d): last_entry=%xh\n",
814 	    qlge->instance, qlge->nic_config.last_entry));
815 
816 	QL_PRINT(DBG_FLASH, ("(%d): subsys_vendor_id=%xh\n",
817 	    qlge->instance, qlge->nic_config.subsys_vendor_id));
818 	QL_PRINT(DBG_FLASH, ("(%d): subsys_device_id=%xh\n",
819 	    qlge->instance, qlge->nic_config.subsys_device_id));
820 
821 	if (chksum != 0 || qlge->nic_config.signature !=
822 	    FLASH_NIC_CONFIG_SIGNATURE || qlge->nic_config.version != 1) {
823 		cmn_err(CE_WARN,
824 		    "invalid flash nic configuration table: chksum %x, "
825 		    "signature %x, version %x",
826 		    chksum, qlge->nic_config.signature,
827 		    qlge->nic_config.version);
828 		return (DDI_FAILURE);
829 	}
830 
831 	return (DDI_SUCCESS);
832 }
833 
834 int
835 ql_flash_vpd(qlge_t *qlge, uint8_t *buf)
836 {
837 	uint32_t cnt;
838 	uint16_t chksum, *bp, data;
839 	int rval;
840 	uint32_t vpd_size;
841 
842 	if (buf == NULL) {
843 		cmn_err(CE_WARN, "%s(%d) buffer is not available.",
844 		    __func__, qlge->instance);
845 		return (DDI_FAILURE);
846 	}
847 
848 	if (!qlge->flash_vpd_addr) {
849 		if (qlge->func_number == qlge->fn0_net)
850 			qlge->flash_vpd_addr = ISP_8100_VPD0_ADDR;
851 		else
852 			qlge->flash_vpd_addr = ISP_8100_VPD1_ADDR;
853 		vpd_size = ISP_8100_VPD0_SIZE;
854 	}
855 	rval = qlge_dump_fcode(qlge, buf, vpd_size, qlge->flash_vpd_addr);
856 
857 	if (rval != DDI_SUCCESS) {
858 		cmn_err(CE_WARN, "%s(%d)read error",
859 		    __func__, qlge->instance);
860 		bzero(buf, vpd_size);
861 		return (rval);
862 	}
863 
864 	QL_DUMP(DBG_FLASH, "flash vpd table raw data:\n", buf, 8, vpd_size);
865 
866 	chksum = 0;
867 	data = 0;
868 	bp = (uint16_t *)(void *)buf;
869 	for (cnt = 0; cnt < (vpd_size/2); cnt++) {
870 		data = *bp;
871 		LITTLE_ENDIAN_16(&data);
872 		chksum += data;
873 		bp++;
874 	}
875 	if (chksum != 0) {
876 		cmn_err(CE_WARN, "%s(%d) invalid flash vpd table",
877 		    __func__, qlge->instance);
878 		return (DDI_FAILURE);
879 	}
880 	return (DDI_SUCCESS);
881 }
882 
883 int
884 ql_get_flash_params(qlge_t *qlge)
885 {
886 	int rval = DDI_SUCCESS;
887 
888 	/* Get semaphore to access Flash Address and Flash Data Registers */
889 	if (ql_sem_spinlock(qlge, QL_FLASH_SEM_MASK)) {
890 		rval = DDI_FAILURE;
891 		goto out;
892 	}
893 	/* do test read of flash ID */
894 	rval = ql_flash_id(qlge);
895 	if (rval != DDI_SUCCESS)
896 		goto out;
897 
898 	/*
899 	 * Temporarily set the fdesc.flash_size to
900 	 * 4M flash size to avoid failing of ql_dump_focde.
901 	 */
902 	qlge->fdesc.flash_size = 4096 * 1024; /* ie. 4M bytes */
903 
904 	/* Default flash descriptor table. */
905 	qlge->fdesc.write_statusreg_cmd = 1;
906 	qlge->fdesc.write_enable_bits = 0;
907 	qlge->fdesc.unprotect_sector_cmd = 0;
908 	qlge->fdesc.protect_sector_cmd = 0;
909 	qlge->fdesc.write_disable_bits = 0x9c;
910 	qlge->fdesc.block_size = 0x10000;
911 	qlge->fdesc.erase_cmd = 0xd8;
912 
913 	/* ! todo : should read from fltds! */
914 	/* !ql_get_flash_params(qlge); */
915 	qlge->fltds.flt_addr_hi = 0x36;
916 	qlge->fltds.flt_addr_lo = 0x1000;
917 	/* read all other tables from Flash memory */
918 	if (ql_flash_flt(qlge) != DDI_SUCCESS) {
919 		if (CFG_IST(qlge, CFG_CHIP_8100)) {
920 			qlge->flash_fdt_addr = ISP_8100_FDT_ADDR; /* 0x360000 */
921 			if (qlge->func_number == qlge->fn0_net)
922 				/* 0x140200 */
923 				qlge->flash_nic_config_table_addr =
924 				    ISP_8100_NIC_PARAM0_ADDR;
925 			else
926 				/* 0x140600 */
927 				qlge->flash_nic_config_table_addr =
928 				    ISP_8100_NIC_PARAM1_ADDR;
929 		}
930 	}
931 	(void) ql_flash_desc(qlge);
932 	(void) ql_flash_nic_config(qlge);
933 
934 out:
935 	ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
936 
937 	return (rval);
938 }
939 
940 /*
941  * ql_setup_flash
942  * Gets the manufacturer and id number of the flash chip,
943  * and sets up the size parameter.
944  */
945 int
946 ql_setup_flash(qlge_t *qlge)
947 {
948 	int rval = DDI_SUCCESS;
949 
950 	if (qlge->flash_fltds_addr != 0) {
951 		return (rval);
952 	}
953 	if (ql_sem_spinlock(qlge, QL_FLASH_SEM_MASK)) {
954 		rval = DDI_FAILURE;
955 		goto out;
956 	}
957 	/* try reading flash ID */
958 	rval = ql_flash_id(qlge);
959 	if (rval != DDI_SUCCESS)
960 		goto out;
961 
962 	/* Default flash descriptor table. */
963 	qlge->fdesc.write_statusreg_cmd = 1;
964 	qlge->fdesc.write_enable_bits = 0;
965 	qlge->fdesc.unprotect_sector_cmd = 0;
966 	qlge->fdesc.protect_sector_cmd = 0;
967 	qlge->fdesc.write_disable_bits = 0x9c;
968 	qlge->fdesc.block_size = 0x10000;
969 	qlge->fdesc.erase_cmd = 0xd8;
970 	/* 1 Get the location of Flash Layout Table Data Structure (FLTDS) */
971 	if (ql_find_flash_layout_table_data_structure_addr(qlge)
972 	    == DDI_SUCCESS) {
973 		/* 2,read fltds */
974 		if (ql_flash_fltds(qlge) == DDI_SUCCESS) {
975 			/*
976 			 * 3,search for flash descriptor table (FDT)
977 			 * and Nic Configuration Table indices
978 			 */
979 			if ((qlge->flash_fdt_addr == 0) ||
980 			    (qlge->flash_nic_config_table_addr == 0)) {
981 				rval = ql_flash_flt(qlge);
982 				if (rval == DDI_SUCCESS) {
983 					(void) ql_flash_desc(qlge);
984 					(void) ql_flash_nic_config(qlge);
985 				} else {
986 					rval = DDI_FAILURE;
987 					goto out;
988 				}
989 			}
990 		} else {
991 			rval = DDI_FAILURE;
992 			goto out;
993 		}
994 	} else {
995 		rval = DDI_FAILURE;
996 		goto out;
997 	}
998 out:
999 	ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
1000 
1001 	return (rval);
1002 
1003 }
1004 
1005 /*
1006  * ql_change_endian
1007  * Change endianess of byte array.
1008  */
1009 void
1010 ql_change_endian(uint8_t buf[], size_t size)
1011 {
1012 	uint8_t byte;
1013 	size_t cnt1;
1014 	size_t cnt;
1015 
1016 	cnt1 = size - 1;
1017 	for (cnt = 0; cnt < size / 2; cnt++) {
1018 		byte = buf[cnt1];
1019 		buf[cnt1] = buf[cnt];
1020 		buf[cnt] = byte;
1021 		cnt1--;
1022 	}
1023 }
1024 
1025 static int
1026 ql_wait_flash_reg_ready(qlge_t *qlge, uint32_t wait_bit)
1027 {
1028 	uint32_t reg_status;
1029 	int rtn_val = DDI_SUCCESS;
1030 	uint32_t delay = 300000;
1031 
1032 	do {
1033 		reg_status = ql_read_reg(qlge, REG_FLASH_ADDRESS);
1034 		if (reg_status & FLASH_ERR_FLAG) {
1035 			cmn_err(CE_WARN,
1036 			    "%s(%d) flash address register error bit set!",
1037 			    __func__, qlge->instance);
1038 			rtn_val = DDI_FAILURE;
1039 			break;
1040 		}
1041 		if (reg_status & wait_bit) {
1042 			break;
1043 		}
1044 		drv_usecwait(10);
1045 	} while (--delay);
1046 
1047 	if (delay == 0) {
1048 		cmn_err(CE_WARN,
1049 		    "%s(%d) timeout error!", __func__, qlge->instance);
1050 		rtn_val = DDI_FAILURE;
1051 	}
1052 	return (rtn_val);
1053 }
1054 
1055 /*
1056  * ql_read_flash
1057  * Reads a 32bit word from FLASH.
1058  */
1059 static int
1060 ql_read_flash(qlge_t *qlge, uint32_t faddr, uint32_t *bp)
1061 {
1062 	int rval = DDI_SUCCESS;
1063 
1064 	ql_write_reg(qlge, REG_FLASH_ADDRESS, faddr | FLASH_R_FLAG);
1065 
1066 	/* Wait for READ cycle to complete. */
1067 	rval = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG);
1068 
1069 	if (rval == DDI_SUCCESS) {
1070 		*bp = ql_read_reg(qlge, REG_FLASH_DATA);
1071 	}
1072 	return (rval);
1073 }
1074 
1075 static int
1076 ql_read_flash_status(qlge_t *qlge, uint8_t *value)
1077 {
1078 	int rtn_val = DDI_SUCCESS;
1079 	uint32_t data, cmd = FLASH_CONF_ADDR | FLASH_R_FLAG;
1080 
1081 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1082 	    != DDI_SUCCESS) {
1083 		return (rtn_val);
1084 	}
1085 	cmd |= FLASH_RDSR_CMD /* 0x05 */;
1086 	ql_write_reg(qlge, REG_FLASH_ADDRESS, cmd);
1087 	if ((rtn_val = ql_wait_flash_reg_ready(qlge,
1088 	    FLASH_RDY_FLAG | FLASH_R_FLAG)) != DDI_SUCCESS) {
1089 		return (rtn_val);
1090 	}
1091 	data = ql_read_reg(qlge, REG_FLASH_DATA);
1092 	*value = (uint8_t)(data & 0xff);
1093 	return (rtn_val);
1094 }
1095 
1096 static int
1097 ql_flash_write_enable(qlge_t *qlge)
1098 {
1099 	uint8_t reg_status;
1100 	int rtn_val = DDI_SUCCESS;
1101 	uint32_t cmd = FLASH_CONF_ADDR;
1102 	uint32_t delay = 300000;
1103 
1104 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1105 	    != DDI_SUCCESS) {
1106 		cmn_err(CE_WARN,
1107 		    "%s(%d) timeout!", __func__, qlge->instance);
1108 		rtn_val = DDI_FAILURE;
1109 		return (rtn_val);
1110 	}
1111 	cmd |= qlge->fdesc.write_enable_cmd;
1112 	ql_write_reg(qlge, REG_FLASH_ADDRESS, cmd);
1113 	/* wait for WEL bit set */
1114 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1115 	    == DDI_SUCCESS) {
1116 		do {
1117 			(void) ql_read_flash_status(qlge, &reg_status);
1118 			if (reg_status & BIT_1)
1119 				break;
1120 			drv_usecwait(10);
1121 		} while (--delay);
1122 	}
1123 	if (delay == 0) {
1124 		cmn_err(CE_WARN,
1125 		    "%s(%d) timeout error! flash status reg: %x",
1126 		    __func__, qlge->instance, reg_status);
1127 		rtn_val = DDI_FAILURE;
1128 	}
1129 	return (rtn_val);
1130 }
1131 
1132 static int
1133 ql_flash_erase_sector(qlge_t *qlge, uint32_t sectorAddr)
1134 {
1135 	int rtn_val = DDI_SUCCESS;
1136 	uint32_t data, cmd = FLASH_CONF_ADDR;
1137 	uint32_t delay = 300000;
1138 	uint8_t flash_status;
1139 
1140 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1141 	    != DDI_SUCCESS) {
1142 		return (rtn_val);
1143 	}
1144 
1145 	cmd |= (0x0300 | qlge->fdesc.erase_cmd);
1146 	data = ((sectorAddr & 0xff) << 16) | (sectorAddr & 0xff00) |
1147 	    ((sectorAddr & 0xff0000) >> 16);
1148 
1149 	ql_write_reg(qlge, REG_FLASH_DATA, data);
1150 	ql_write_reg(qlge, REG_FLASH_ADDRESS, cmd);
1151 
1152 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1153 	    == DDI_SUCCESS) {
1154 		/* wait Write In Progress (WIP) bit to reset */
1155 		do {
1156 			(void) ql_read_flash_status(qlge, &flash_status);
1157 			if ((flash_status & BIT_0 /* WIP */) == 0)
1158 				break;
1159 			drv_usecwait(10);
1160 		} while (--delay);
1161 	} else {
1162 		return (rtn_val);
1163 	}
1164 
1165 	if (delay == 0) {
1166 		cmn_err(CE_WARN,
1167 		    "%s(%d) timeout error! flash status reg: %x",
1168 		    __func__, qlge->instance, flash_status);
1169 		rtn_val = DDI_FAILURE;
1170 	}
1171 	return (rtn_val);
1172 }
1173 
1174 /*
1175  * ql_write_flash
1176  * Writes a 32bit word to FLASH.
1177  */
1178 static int
1179 ql_write_flash(qlge_t *qlge, uint32_t addr, uint32_t data)
1180 {
1181 	int rval = DDI_SUCCESS;
1182 	uint32_t delay = 300000;
1183 	uint8_t flash_status;
1184 
1185 	ql_write_reg(qlge, REG_FLASH_DATA, data);
1186 	ql_read_reg(qlge, REG_FLASH_DATA);
1187 	ql_write_reg(qlge, REG_FLASH_ADDRESS, addr);
1188 
1189 	if ((rval = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1190 	    == DDI_SUCCESS) {
1191 		if ((addr & FLASH_ADDR_MASK) == FLASH_CONF_ADDR) {
1192 			/* wait Write In Progress (WIP) bit to reset */
1193 			do {
1194 				(void) ql_read_flash_status(qlge,
1195 				    &flash_status);
1196 				if ((flash_status & BIT_0 /* WIP */) == 0)
1197 					break;
1198 				drv_usecwait(10);
1199 			} while (--delay);
1200 		}
1201 	} else {
1202 		return (rval);
1203 	}
1204 
1205 	if (delay == 0) {
1206 		cmn_err(CE_WARN,
1207 		    "%s(%d) timeout error! flash status reg: %x",
1208 		    __func__, qlge->instance, flash_status);
1209 		rval = DDI_FAILURE;
1210 	}
1211 
1212 	return (rval);
1213 }
1214 
1215 /*
1216  * ql_unprotect_flash
1217  * Enable writes
1218  */
1219 static int
1220 ql_unprotect_flash(qlge_t *qlge)
1221 {
1222 	int fdata, rtn_val;
1223 
1224 	if ((rtn_val = ql_flash_write_enable(qlge)) != DDI_SUCCESS) {
1225 		return (rtn_val);
1226 	}
1227 
1228 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1229 	    != DDI_SUCCESS) {
1230 		return (rtn_val);
1231 	}
1232 
1233 	/*
1234 	 * Remove block write protection (SST and ST) and
1235 	 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
1236 	 * Unprotect sectors.
1237 	 */
1238 	(void) ql_write_flash(qlge,
1239 	    FLASH_CONF_ADDR | 0x100 | qlge->fdesc.write_statusreg_cmd,
1240 	    qlge->fdesc.write_enable_bits);
1241 
1242 	if (qlge->fdesc.unprotect_sector_cmd != 0) {
1243 		for (fdata = 0; fdata < 0x10; fdata++) {
1244 			(void) ql_write_flash(qlge, FLASH_CONF_ADDR |
1245 			    0x300 | qlge->fdesc.unprotect_sector_cmd, fdata);
1246 		}
1247 
1248 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x300 |
1249 		    qlge->fdesc.unprotect_sector_cmd, 0x00400f);
1250 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x300 |
1251 		    qlge->fdesc.unprotect_sector_cmd, 0x00600f);
1252 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x300 |
1253 		    qlge->fdesc.unprotect_sector_cmd, 0x00800f);
1254 	}
1255 	rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG);
1256 	return (rtn_val);
1257 }
1258 
1259 /*
1260  * ql_protect_flash
1261  * Disable writes
1262  */
1263 static int
1264 ql_protect_flash(qlge_t *qlge)
1265 {
1266 	int fdata, rtn_val;
1267 
1268 	if ((rtn_val = ql_flash_write_enable(qlge)) != DDI_SUCCESS) {
1269 		return (rtn_val);
1270 	}
1271 
1272 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1273 	    != DDI_SUCCESS) {
1274 		return (rtn_val);
1275 	}
1276 	/*
1277 	 * Protect sectors.
1278 	 * Set block write protection (SST and ST) and
1279 	 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
1280 	 */
1281 
1282 	if (qlge->fdesc.protect_sector_cmd != 0) {
1283 		for (fdata = 0; fdata < 0x10; fdata++) {
1284 			(void) ql_write_flash(qlge, FLASH_CONF_ADDR |
1285 			    0x330 | qlge->fdesc.protect_sector_cmd, fdata);
1286 		}
1287 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x330 |
1288 		    qlge->fdesc.protect_sector_cmd, 0x00400f);
1289 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x330 |
1290 		    qlge->fdesc.protect_sector_cmd, 0x00600f);
1291 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x330 |
1292 		    qlge->fdesc.protect_sector_cmd, 0x00800f);
1293 
1294 		(void) ql_write_flash(qlge,
1295 		    FLASH_CONF_ADDR | 0x101, 0x80);
1296 	} else {
1297 		(void) ql_write_flash(qlge,
1298 		    FLASH_CONF_ADDR | 0x100 | qlge->fdesc.write_statusreg_cmd,
1299 		    qlge->fdesc.write_disable_bits /* 0x9c */);
1300 	}
1301 
1302 	rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG);
1303 	return (rtn_val);
1304 }
1305 
1306 /*
1307  * ql_write_flash_test
1308  * test write to a flash sector that is not being used
1309  */
1310 void
1311 ql_write_flash_test(qlge_t *qlge, uint32_t test_addr)
1312 {
1313 	uint32_t old_data, data;
1314 	uint32_t addr = 0;
1315 
1316 	addr = (test_addr / 4);
1317 	(void) ql_read_flash(qlge, addr, &old_data);
1318 	QL_PRINT(DBG_FLASH, ("read addr %x old value %x\n", test_addr,
1319 	    old_data));
1320 
1321 	/* enable writing to flash */
1322 	(void) ql_unprotect_flash(qlge);
1323 
1324 	/* erase the sector */
1325 	(void) ql_flash_erase_sector(qlge, test_addr);
1326 	(void) ql_read_flash(qlge, addr, &data);
1327 	QL_PRINT(DBG_FLASH, ("after sector erase, addr %x value %x\n",
1328 	    test_addr, data));
1329 
1330 	/* write new value to it and read back to confirm */
1331 	data = 0x33445566;
1332 	(void) ql_write_flash(qlge, addr, data);
1333 	QL_PRINT(DBG_FLASH, ("new value written to addr %x value %x\n",
1334 	    test_addr, data));
1335 	(void) ql_read_flash(qlge, addr, &data);
1336 	if (data != 0x33445566) {
1337 		cmn_err(CE_WARN, "flash write test failed, get data %x"
1338 		    " after writing", data);
1339 	}
1340 
1341 	/* write old value to it and read back to restore */
1342 	(void) ql_flash_erase_sector(qlge, test_addr);
1343 	(void) ql_write_flash(qlge, addr, old_data);
1344 	(void) ql_read_flash(qlge, addr, &data);
1345 	QL_PRINT(DBG_FLASH, ("write back old value addr %x value %x\n",
1346 	    test_addr, data));
1347 
1348 	/* test done, protect the flash to forbid any more flash writting */
1349 	(void) ql_protect_flash(qlge);
1350 
1351 }
1352 
1353 
1354 void
1355 ql_write_flash_test2(qlge_t *qlge, uint32_t test_addr)
1356 {
1357 	uint32_t data, old_data;
1358 
1359 	(void) qlge_dump_fcode(qlge, (uint8_t *)&old_data, sizeof (old_data),
1360 	    test_addr);
1361 	QL_PRINT(DBG_FLASH, ("read addr %x old value %x\n",
1362 	    test_addr, old_data));
1363 
1364 	data = 0x12345678;
1365 
1366 	QL_PRINT(DBG_FLASH, ("write new test value %x\n", data));
1367 	qlge_load_flash(qlge, (uint8_t *)&data, sizeof (data), 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 	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 }
1406