xref: /illumos-gate/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_flash.c (revision accf27a5824ae84dfac7b089c4325917231a7d15)
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
ql_flash_id(qlge_t * qlge)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
qlge_dump_fcode(qlge_t * qlge,uint8_t * dp,uint32_t size,uint32_t startpos)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
ql_erase_and_write_to_flash(qlge_t * qlge,uint8_t * dp,uint32_t size,uint32_t faddr)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
get_sector_number(qlge_t * qlge,uint32_t faddr,uint32_t * psector)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
qlge_load_flash(qlge_t * qlge,uint8_t * dp,uint32_t len,uint32_t faddr)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
ql_check_pci(qlge_t * qlge,uint8_t * buf,uint32_t * nextpos)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
ql_find_flash_layout_table_data_structure_addr(qlge_t * qlge)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
ql_flash_fltds(qlge_t * qlge)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
ql_flash_flt(qlge_t * qlge)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) flt header version %x unsupported",
552 		    __func__, qlge->instance, qlge->flt.header.version);
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
ql_flash_desc(qlge_t * qlge)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
ql_flash_nic_config(qlge_t * qlge)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
ql_flash_vpd(qlge_t * qlge,uint8_t * buf)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
ql_get_flash_params(qlge_t * qlge)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
ql_setup_flash(qlge_t * qlge)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
ql_change_endian(uint8_t buf[],size_t size)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
ql_wait_flash_reg_ready(qlge_t * qlge,uint32_t wait_bit)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 		if (qlge->fm_enable) {
1051 			ql_fm_ereport(qlge, DDI_FM_DEVICE_NO_RESPONSE);
1052 			atomic_or_32(&qlge->flags, ADAPTER_ERROR);
1053 			ddi_fm_service_impact(qlge->dip, DDI_SERVICE_LOST);
1054 		}
1055 		rtn_val = DDI_FAILURE;
1056 	}
1057 	return (rtn_val);
1058 }
1059 
1060 /*
1061  * ql_read_flash
1062  * Reads a 32bit word from FLASH.
1063  */
1064 static int
ql_read_flash(qlge_t * qlge,uint32_t faddr,uint32_t * bp)1065 ql_read_flash(qlge_t *qlge, uint32_t faddr, uint32_t *bp)
1066 {
1067 	int rval = DDI_SUCCESS;
1068 
1069 	ql_write_reg(qlge, REG_FLASH_ADDRESS, faddr | FLASH_R_FLAG);
1070 
1071 	/* Wait for READ cycle to complete. */
1072 	rval = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG);
1073 
1074 	if (rval == DDI_SUCCESS) {
1075 		*bp = ql_read_reg(qlge, REG_FLASH_DATA);
1076 	}
1077 	return (rval);
1078 }
1079 
1080 static int
ql_read_flash_status(qlge_t * qlge,uint8_t * value)1081 ql_read_flash_status(qlge_t *qlge, uint8_t *value)
1082 {
1083 	int rtn_val = DDI_SUCCESS;
1084 	uint32_t data, cmd = FLASH_CONF_ADDR | FLASH_R_FLAG;
1085 
1086 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1087 	    != DDI_SUCCESS) {
1088 		return (rtn_val);
1089 	}
1090 	cmd |= FLASH_RDSR_CMD /* 0x05 */;
1091 	ql_write_reg(qlge, REG_FLASH_ADDRESS, cmd);
1092 	if ((rtn_val = ql_wait_flash_reg_ready(qlge,
1093 	    FLASH_RDY_FLAG | FLASH_R_FLAG)) != DDI_SUCCESS) {
1094 		return (rtn_val);
1095 	}
1096 	data = ql_read_reg(qlge, REG_FLASH_DATA);
1097 	*value = (uint8_t)(data & 0xff);
1098 	return (rtn_val);
1099 }
1100 
1101 static int
ql_flash_write_enable(qlge_t * qlge)1102 ql_flash_write_enable(qlge_t *qlge)
1103 {
1104 	uint8_t reg_status;
1105 	int rtn_val = DDI_SUCCESS;
1106 	uint32_t cmd = FLASH_CONF_ADDR;
1107 	uint32_t delay = 300000;
1108 
1109 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1110 	    != DDI_SUCCESS) {
1111 		cmn_err(CE_WARN,
1112 		    "%s(%d) timeout!", __func__, qlge->instance);
1113 		rtn_val = DDI_FAILURE;
1114 		return (rtn_val);
1115 	}
1116 	cmd |= qlge->fdesc.write_enable_cmd;
1117 	ql_write_reg(qlge, REG_FLASH_ADDRESS, cmd);
1118 	/* wait for WEL bit set */
1119 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1120 	    == DDI_SUCCESS) {
1121 		do {
1122 			(void) ql_read_flash_status(qlge, &reg_status);
1123 			if (reg_status & BIT_1)
1124 				break;
1125 			drv_usecwait(10);
1126 		} while (--delay);
1127 	}
1128 	if (delay == 0) {
1129 		cmn_err(CE_WARN,
1130 		    "%s(%d) timeout error! flash status reg: %x",
1131 		    __func__, qlge->instance, reg_status);
1132 		rtn_val = DDI_FAILURE;
1133 	}
1134 	return (rtn_val);
1135 }
1136 
1137 static int
ql_flash_erase_sector(qlge_t * qlge,uint32_t sectorAddr)1138 ql_flash_erase_sector(qlge_t *qlge, uint32_t sectorAddr)
1139 {
1140 	int rtn_val = DDI_SUCCESS;
1141 	uint32_t data, cmd = FLASH_CONF_ADDR;
1142 	uint32_t delay = 300000;
1143 	uint8_t flash_status;
1144 
1145 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1146 	    != DDI_SUCCESS) {
1147 		return (rtn_val);
1148 	}
1149 
1150 	cmd |= (0x0300 | qlge->fdesc.erase_cmd);
1151 	data = ((sectorAddr & 0xff) << 16) | (sectorAddr & 0xff00) |
1152 	    ((sectorAddr & 0xff0000) >> 16);
1153 
1154 	ql_write_reg(qlge, REG_FLASH_DATA, data);
1155 	ql_write_reg(qlge, REG_FLASH_ADDRESS, cmd);
1156 
1157 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1158 	    == DDI_SUCCESS) {
1159 		/* wait Write In Progress (WIP) bit to reset */
1160 		do {
1161 			(void) ql_read_flash_status(qlge, &flash_status);
1162 			if ((flash_status & BIT_0 /* WIP */) == 0)
1163 				break;
1164 			drv_usecwait(10);
1165 		} while (--delay);
1166 	} else {
1167 		return (rtn_val);
1168 	}
1169 
1170 	if (delay == 0) {
1171 		cmn_err(CE_WARN,
1172 		    "%s(%d) timeout error! flash status reg: %x",
1173 		    __func__, qlge->instance, flash_status);
1174 		rtn_val = DDI_FAILURE;
1175 	}
1176 	return (rtn_val);
1177 }
1178 
1179 /*
1180  * ql_write_flash
1181  * Writes a 32bit word to FLASH.
1182  */
1183 static int
ql_write_flash(qlge_t * qlge,uint32_t addr,uint32_t data)1184 ql_write_flash(qlge_t *qlge, uint32_t addr, uint32_t data)
1185 {
1186 	int rval = DDI_SUCCESS;
1187 	uint32_t delay = 300000;
1188 	uint8_t flash_status;
1189 
1190 	ql_write_reg(qlge, REG_FLASH_DATA, data);
1191 	(void) ql_read_reg(qlge, REG_FLASH_DATA);
1192 	ql_write_reg(qlge, REG_FLASH_ADDRESS, addr);
1193 
1194 	if ((rval = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1195 	    == DDI_SUCCESS) {
1196 		if ((addr & FLASH_ADDR_MASK) == FLASH_CONF_ADDR) {
1197 			/* wait Write In Progress (WIP) bit to reset */
1198 			do {
1199 				(void) ql_read_flash_status(qlge,
1200 				    &flash_status);
1201 				if ((flash_status & BIT_0 /* WIP */) == 0)
1202 					break;
1203 				drv_usecwait(10);
1204 			} while (--delay);
1205 		}
1206 	} else {
1207 		return (rval);
1208 	}
1209 
1210 	if (delay == 0) {
1211 		cmn_err(CE_WARN,
1212 		    "%s(%d) timeout error! flash status reg: %x",
1213 		    __func__, qlge->instance, flash_status);
1214 		rval = DDI_FAILURE;
1215 	}
1216 
1217 	return (rval);
1218 }
1219 
1220 /*
1221  * ql_unprotect_flash
1222  * Enable writes
1223  */
1224 static int
ql_unprotect_flash(qlge_t * qlge)1225 ql_unprotect_flash(qlge_t *qlge)
1226 {
1227 	int fdata, rtn_val;
1228 
1229 	if ((rtn_val = ql_flash_write_enable(qlge)) != DDI_SUCCESS) {
1230 		return (rtn_val);
1231 	}
1232 
1233 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1234 	    != DDI_SUCCESS) {
1235 		return (rtn_val);
1236 	}
1237 
1238 	/*
1239 	 * Remove block write protection (SST and ST) and
1240 	 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
1241 	 * Unprotect sectors.
1242 	 */
1243 	(void) ql_write_flash(qlge,
1244 	    FLASH_CONF_ADDR | 0x100 | qlge->fdesc.write_statusreg_cmd,
1245 	    qlge->fdesc.write_enable_bits);
1246 
1247 	if (qlge->fdesc.unprotect_sector_cmd != 0) {
1248 		for (fdata = 0; fdata < 0x10; fdata++) {
1249 			(void) ql_write_flash(qlge, FLASH_CONF_ADDR |
1250 			    0x300 | qlge->fdesc.unprotect_sector_cmd, fdata);
1251 		}
1252 
1253 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x300 |
1254 		    qlge->fdesc.unprotect_sector_cmd, 0x00400f);
1255 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x300 |
1256 		    qlge->fdesc.unprotect_sector_cmd, 0x00600f);
1257 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x300 |
1258 		    qlge->fdesc.unprotect_sector_cmd, 0x00800f);
1259 	}
1260 	rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG);
1261 	return (rtn_val);
1262 }
1263 
1264 /*
1265  * ql_protect_flash
1266  * Disable writes
1267  */
1268 static int
ql_protect_flash(qlge_t * qlge)1269 ql_protect_flash(qlge_t *qlge)
1270 {
1271 	int fdata, rtn_val;
1272 
1273 	if ((rtn_val = ql_flash_write_enable(qlge)) != DDI_SUCCESS) {
1274 		return (rtn_val);
1275 	}
1276 
1277 	if ((rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG))
1278 	    != DDI_SUCCESS) {
1279 		return (rtn_val);
1280 	}
1281 	/*
1282 	 * Protect sectors.
1283 	 * Set block write protection (SST and ST) and
1284 	 * Sector/Block Protection Register Lock (SST, ST, ATMEL).
1285 	 */
1286 
1287 	if (qlge->fdesc.protect_sector_cmd != 0) {
1288 		for (fdata = 0; fdata < 0x10; fdata++) {
1289 			(void) ql_write_flash(qlge, FLASH_CONF_ADDR |
1290 			    0x330 | qlge->fdesc.protect_sector_cmd, fdata);
1291 		}
1292 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x330 |
1293 		    qlge->fdesc.protect_sector_cmd, 0x00400f);
1294 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x330 |
1295 		    qlge->fdesc.protect_sector_cmd, 0x00600f);
1296 		(void) ql_write_flash(qlge, FLASH_CONF_ADDR | 0x330 |
1297 		    qlge->fdesc.protect_sector_cmd, 0x00800f);
1298 
1299 		(void) ql_write_flash(qlge,
1300 		    FLASH_CONF_ADDR | 0x101, 0x80);
1301 	} else {
1302 		(void) ql_write_flash(qlge,
1303 		    FLASH_CONF_ADDR | 0x100 | qlge->fdesc.write_statusreg_cmd,
1304 		    qlge->fdesc.write_disable_bits /* 0x9c */);
1305 	}
1306 
1307 	rtn_val = ql_wait_flash_reg_ready(qlge, FLASH_RDY_FLAG);
1308 	return (rtn_val);
1309 }
1310 
1311 /*
1312  * ql_write_flash_test
1313  * test write to a flash sector that is not being used
1314  */
1315 void
ql_write_flash_test(qlge_t * qlge,uint32_t test_addr)1316 ql_write_flash_test(qlge_t *qlge, uint32_t test_addr)
1317 {
1318 	uint32_t old_data, data;
1319 	uint32_t addr = 0;
1320 
1321 	addr = (test_addr / 4);
1322 	(void) ql_read_flash(qlge, addr, &old_data);
1323 	QL_PRINT(DBG_FLASH, ("read addr %x old value %x\n", test_addr,
1324 	    old_data));
1325 
1326 	/* enable writing to flash */
1327 	(void) ql_unprotect_flash(qlge);
1328 
1329 	/* erase the sector */
1330 	(void) ql_flash_erase_sector(qlge, test_addr);
1331 	(void) ql_read_flash(qlge, addr, &data);
1332 	QL_PRINT(DBG_FLASH, ("after sector erase, addr %x value %x\n",
1333 	    test_addr, data));
1334 
1335 	/* write new value to it and read back to confirm */
1336 	data = 0x33445566;
1337 	(void) ql_write_flash(qlge, addr, data);
1338 	QL_PRINT(DBG_FLASH, ("new value written to addr %x value %x\n",
1339 	    test_addr, data));
1340 	(void) ql_read_flash(qlge, addr, &data);
1341 	if (data != 0x33445566) {
1342 		cmn_err(CE_WARN, "flash write test failed, get data %x"
1343 		    " after writing", data);
1344 	}
1345 
1346 	/* write old value to it and read back to restore */
1347 	(void) ql_flash_erase_sector(qlge, test_addr);
1348 	(void) ql_write_flash(qlge, addr, old_data);
1349 	(void) ql_read_flash(qlge, addr, &data);
1350 	QL_PRINT(DBG_FLASH, ("write back old value addr %x value %x\n",
1351 	    test_addr, data));
1352 
1353 	/* test done, protect the flash to forbid any more flash writting */
1354 	(void) ql_protect_flash(qlge);
1355 
1356 }
1357 
1358 
1359 void
ql_write_flash_test2(qlge_t * qlge,uint32_t test_addr)1360 ql_write_flash_test2(qlge_t *qlge, uint32_t test_addr)
1361 {
1362 	uint32_t data, old_data;
1363 
1364 	(void) qlge_dump_fcode(qlge, (uint8_t *)&old_data, sizeof (old_data),
1365 	    test_addr);
1366 	QL_PRINT(DBG_FLASH, ("read addr %x old value %x\n",
1367 	    test_addr, old_data));
1368 
1369 	data = 0x12345678;
1370 
1371 	QL_PRINT(DBG_FLASH, ("write new test value %x\n", data));
1372 	(void) qlge_load_flash(qlge, (uint8_t *)&data, sizeof (data),
1373 	    test_addr);
1374 	(void) qlge_dump_fcode(qlge, (uint8_t *)&data, sizeof (data),
1375 	    test_addr);
1376 	if (data != 0x12345678) {
1377 		cmn_err(CE_WARN,
1378 		    "flash write test failed, get data %x after writing",
1379 		    data);
1380 	}
1381 	/* write old value to it and read back to restore */
1382 	(void) qlge_load_flash(qlge, (uint8_t *)&old_data, sizeof (old_data),
1383 	    test_addr);
1384 	(void) qlge_dump_fcode(qlge, (uint8_t *)&data, sizeof (data),
1385 	    test_addr);
1386 	QL_PRINT(DBG_FLASH, ("write back old value addr %x value %x verified\n",
1387 	    test_addr, data));
1388 }
1389 
1390 /*
1391  * ql_sem_flash_lock
1392  * Flash memory is a shared resource amoung various PCI Functions, so,
1393  * anyone wants to access flash memory, it needs to lock it first.
1394  */
1395 int
ql_sem_flash_lock(qlge_t * qlge)1396 ql_sem_flash_lock(qlge_t *qlge)
1397 {
1398 	int rval = DDI_SUCCESS;
1399 
1400 	/* Get semaphore to access Flash Address and Flash Data Registers */
1401 	if (ql_sem_spinlock(qlge, QL_FLASH_SEM_MASK)) {
1402 		rval = DDI_FAILURE;
1403 	}
1404 	return (rval);
1405 }
1406 
1407 void
ql_sem_flash_unlock(qlge_t * qlge)1408 ql_sem_flash_unlock(qlge_t *qlge)
1409 {
1410 	ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
1411 }
1412