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, &reg_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 }