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         if (temp == NULL) {
 245                 cmn_err(CE_WARN, "%s(%d): Unable to allocate buffer",
 246                     __func__, qlge->instance);
 247                 ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
 248                 return (DDI_FAILURE);
 249         }
 250 
 251         (void) ql_unprotect_flash(qlge);
 252 
 253         get_sector_number(qlge, faddr, &start_block);
 254         get_sector_number(qlge, faddr + len - 1, &end_block);
 255 
 256         QL_PRINT(DBG_FLASH, ("%s(%d) start_block %x, end_block %x\n",
 257             __func__, qlge->instance, start_block, end_block));
 258 
 259         for (num = start_block; num <= end_block; num++) {
 260                 QL_PRINT(DBG_FLASH,
 261                     ("%s(%d) sector_size 0x%x, sector read addr %x\n",
 262                     __func__, qlge->instance, sector_size, num * sector_size));
 263                 /* read one whole sector flash data to buffer */
 264                 rval = qlge_dump_fcode(qlge, (uint8_t *)temp, sector_size,
 265                     num * sector_size);
 266 
 267                 start_byte = num * sector_size;
 268                 end_byte = start_byte + sector_size -1;
 269                 if (start_byte < faddr)
 270                         start_byte = faddr;
 271                 if (end_byte > (faddr + len))
 272                         end_byte = (faddr + len - 1);
 273 
 274                 addr_src = start_byte - faddr;
 275                 addr_desc = start_byte - num * sector_size;
 276                 bp = (caddr_t)dp + addr_src;
 277                 bdesc = (caddr_t)temp + addr_desc;
 278                 bcopy(bp, bdesc, (end_byte - start_byte + 1));
 279 
 280                 /* write the whole sector data to flash */
 281                 if (ql_erase_and_write_to_flash(qlge, temp, sector_size,
 282                     num * sector_size) != DDI_SUCCESS)
 283                         goto out;
 284         }
 285         rval = DDI_SUCCESS;
 286 out:
 287         (void) ql_protect_flash(qlge);
 288         kmem_free(temp, sector_size);
 289 
 290         ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
 291 
 292         if (rval != DDI_SUCCESS) {
 293                 cmn_err(CE_WARN, "%s(%d failed=%xh",
 294                     __func__, qlge->instance, rval);
 295         }
 296 
 297         return (rval);
 298 }
 299 
 300 
 301 /*
 302  * ql_check_pci
 303  * checks the passed buffer for a valid pci signature and
 304  * expected (and in range) pci length values.
 305  * On successful pci check, nextpos adjusted to next pci header.
 306  */
 307 static int
 308 ql_check_pci(qlge_t *qlge, uint8_t *buf, uint32_t *nextpos)
 309 {
 310         pci_header_t *pcih;
 311         pci_data_t *pcid;
 312         uint32_t doff;
 313         uint8_t *pciinfo;
 314         uint32_t image_size = 0;
 315         int rval = CONTINUE_SEARCH;
 316 
 317         QL_PRINT(DBG_FLASH, ("%s(%d) check image at 0x%x\n",
 318             __func__, qlge->instance, *nextpos));
 319 
 320         if (buf != NULL) {
 321                 pciinfo = buf;
 322         } else {
 323                 cmn_err(CE_WARN, "%s(%d) failed, null buf ptr passed",
 324                     __func__, qlge->instance);
 325                 return (STOP_SEARCH);
 326         }
 327 
 328         /* get the pci header image length */
 329         pcih = (pci_header_t *)pciinfo;
 330 
 331         doff = pcih->dataoffset[1];
 332         doff <<= 8;
 333         doff |= pcih->dataoffset[0];
 334 
 335         /* some header section sanity check */
 336         if (pcih->signature[0] != PCI_HEADER0 /* '55' */ ||
 337             pcih->signature[1] != PCI_HEADER1 /* 'AA' */ || doff > 50) {
 338                 cmn_err(CE_WARN, "%s(%d) image format error: s0=%xh, s1=%xh,"
 339                     "off=%xh\n", __func__, qlge->instance,
 340                     pcih->signature[0], pcih->signature[1], doff);
 341                 return (STOP_SEARCH);
 342         }
 343 
 344         pcid = (pci_data_t *)(pciinfo + doff);
 345 
 346         /* a slight sanity data section check */
 347         if (pcid->signature[0] != 'P' || pcid->signature[1] != 'C' ||
 348             pcid->signature[2] != 'I' || pcid->signature[3] != 'R') {
 349                 cmn_err(CE_WARN, "%s(%d) failed, data sig mismatch!",
 350                     __func__, qlge->instance);
 351                 return (STOP_SEARCH);
 352         }
 353         image_size =
 354             (pcid->imagelength[0] | (pcid->imagelength[1] << 8))*
 355             PCI_SECTOR_SIZE /* 512 */;
 356 
 357         switch (pcid->codetype) {
 358         case PCI_CODE_X86PC:
 359                 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_BIOS \n",
 360                     __func__, qlge->instance));
 361                 break;
 362         case PCI_CODE_FCODE:
 363                 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_FCODE \n",
 364                     __func__, qlge->instance));
 365                 break;
 366         case PCI_CODE_EFI:
 367                 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_EFI \n",
 368                     __func__, qlge->instance));
 369                 break;
 370         case PCI_CODE_HPPA:
 371                 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is PCI_CODE_HPPA \n",
 372                     __func__, qlge->instance));
 373                 break;
 374         default:
 375                 QL_PRINT(DBG_FLASH, ("%s(%d) boot image is FTYPE_UNKNOWN \n",
 376                     __func__, qlge->instance));
 377                 break;
 378         }
 379 
 380         QL_PRINT(DBG_FLASH, ("%s(%d) image size %x at %x\n",
 381             __func__, qlge->instance, image_size, *nextpos));
 382 
 383         if (pcid->indicator == PCI_IND_LAST_IMAGE) {
 384                 QL_PRINT(DBG_FLASH, ("%s(%d) last boot image found \n",
 385                     __func__, qlge->instance));
 386                 rval = LAST_IMAGE_FOUND;
 387         } else {
 388                 rval = CONTINUE_SEARCH;
 389         }
 390         /* Get the next flash image address */
 391         *nextpos += image_size;
 392 
 393         return (rval);
 394 }
 395 
 396 /*
 397  * ql_find_flash_layout_table_data_structure
 398  * Find Flash Layout Table Data Structure (FLTDS) that
 399  * is located at the end of last boot image.
 400  * Assume FLTDS is located with first 2M bytes.
 401  * Note:
 402  * Driver must be in stalled state prior to entering or
 403  * add code to this function prior to calling ql_setup_flash()
 404  */
 405 int
 406 ql_find_flash_layout_table_data_structure_addr(qlge_t *qlge)
 407 {
 408         int rval = DDI_FAILURE;
 409         int result = CONTINUE_SEARCH;
 410         uint32_t freadpos = 0;
 411         uint8_t buf[FBUFSIZE];
 412 
 413         if (qlge->flash_fltds_addr != 0) {
 414                 QL_PRINT(DBG_FLASH, ("%s(%d) done already\n",
 415                     __func__, qlge->instance));
 416                 return (DDI_SUCCESS);
 417         }
 418         /*
 419          * Temporarily set the fdesc.flash_size to
 420          * 1M flash size to avoid failing of ql_dump_focde.
 421          */
 422         qlge->fdesc.flash_size = FLASH_FIRMWARE_IMAGE_ADDR;
 423 
 424         while (result == CONTINUE_SEARCH) {
 425 
 426                 if ((rval = qlge_dump_fcode(qlge, buf, FBUFSIZE, freadpos))
 427                     != DDI_SUCCESS) {
 428                         cmn_err(CE_WARN, "%s(%d) qlge_dump_fcode failed"
 429                             " pos=%xh rval=%xh",
 430                             __func__, qlge->instance, freadpos, rval);
 431                         break;
 432                 }
 433                 /*
 434                  * checkout the pci boot image format
 435                  * and get next read address
 436                  */
 437                 result = ql_check_pci(qlge, buf, &freadpos);
 438                 /*
 439                  * find last image? If so, then the freadpos
 440                  * is the address of FLTDS
 441                  */
 442                 if (result == LAST_IMAGE_FOUND) {
 443                         QL_PRINT(DBG_FLASH,
 444                             ("%s(%d) flash layout table data structure "
 445                             "(FLTDS) address is at %x \n", __func__,
 446                             qlge->instance, freadpos));
 447                         qlge->flash_fltds_addr = freadpos;
 448                         rval = DDI_SUCCESS;
 449                         break;
 450                 } else if (result == STOP_SEARCH) {
 451                         cmn_err(CE_WARN, "%s(%d) flash header incorrect,"
 452                             "stop searching",
 453                             __func__, qlge->instance);
 454                         break;
 455                 }
 456         }
 457         return (rval);
 458 }
 459 
 460 /*
 461  * ql_flash_fltds
 462  * Get flash layout table data structure table.
 463  */
 464 static int
 465 ql_flash_fltds(qlge_t *qlge)
 466 {
 467         uint32_t cnt;
 468         uint16_t chksum, *bp, data;
 469         int rval;
 470 
 471         rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->fltds,
 472             sizeof (ql_fltds_t), qlge->flash_fltds_addr);
 473         if (rval != DDI_SUCCESS) {
 474                 cmn_err(CE_WARN, "%s(%d)read error",
 475                     __func__, qlge->instance);
 476                 bzero(&qlge->fltds, sizeof (ql_fltds_t));
 477                 return (rval);
 478         }
 479 
 480         QL_DUMP(DBG_FLASH, "flash layout table data structure:\n",
 481             &qlge->fltds, 8, sizeof (ql_fltds_t));
 482 
 483         chksum = 0;
 484         data = 0;
 485         bp = (uint16_t *)&qlge->fltds;
 486         for (cnt = 0; cnt < (sizeof (ql_fltds_t)) / 2; cnt++) {
 487                 data = *bp;
 488                 LITTLE_ENDIAN_16(&data);
 489                 chksum += data;
 490                 bp++;
 491         }
 492 
 493         LITTLE_ENDIAN_32(&qlge->fltds.signature);
 494         LITTLE_ENDIAN_16(&qlge->fltds.flt_addr_lo);
 495         LITTLE_ENDIAN_16(&qlge->fltds.flt_addr_hi);
 496         LITTLE_ENDIAN_16(&qlge->fltds.checksum);
 497 
 498         QL_PRINT(DBG_FLASH, ("%s(%d) signature %xh\n",
 499             __func__, qlge->instance, qlge->fltds.signature));
 500         QL_PRINT(DBG_FLASH, ("%s(%d) flt_addr_lo %xh\n",
 501             __func__, qlge->instance, qlge->fltds.flt_addr_lo));
 502         QL_PRINT(DBG_FLASH, ("%s(%d) flt_addr_hi %xh\n",
 503             __func__, qlge->instance, qlge->fltds.flt_addr_hi));
 504         QL_PRINT(DBG_FLASH, ("%s(%d) version %xh\n",
 505             __func__, qlge->instance, qlge->fltds.version));
 506         QL_PRINT(DBG_FLASH, ("%s(%d) checksum %xh\n",
 507             __func__, qlge->instance, qlge->fltds.checksum));
 508         /* QFLT */
 509         if (chksum != 0 || qlge->fltds.signature != FLASH_FLTDS_SIGNATURE) {
 510                 cmn_err(CE_WARN, "%s(%d) invalid flash layout table data"
 511                     " structure", __func__, qlge->instance);
 512                 bzero(&qlge->fltds, sizeof (ql_fltds_t));
 513                 return (DDI_FAILURE);
 514         }
 515         return (DDI_SUCCESS);
 516 }
 517 
 518 /*
 519  * ql_flash_flt
 520  * Get flash layout table.
 521  */
 522 int
 523 ql_flash_flt(qlge_t *qlge)
 524 {
 525         uint32_t addr, cnt;
 526         int rval = DDI_FAILURE;
 527         ql_flt_entry_t *entry;
 528         uint8_t region;
 529 
 530         addr = qlge->fltds.flt_addr_hi;
 531         addr <<= 16;
 532         addr |= qlge->fltds.flt_addr_lo;
 533 
 534         /* first read flt header to know how long the table is */
 535         rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->flt.header,
 536             sizeof (ql_flt_header_t), addr);
 537         if (rval != DDI_SUCCESS) {
 538                 cmn_err(CE_WARN, "%s(%d) read flt header at %x error",
 539                     __func__, qlge->instance, addr);
 540                 bzero(&qlge->flt, sizeof (ql_flt_header_t));
 541                 return (rval);
 542         }
 543 
 544         LITTLE_ENDIAN_16(&qlge->flt.header.version);
 545         LITTLE_ENDIAN_16(&qlge->flt.header.length);
 546         LITTLE_ENDIAN_16(&qlge->flt.header.checksum);
 547         LITTLE_ENDIAN_16(&qlge->flt.header.reserved);
 548 
 549         if ((qlge->flt.header.version != 1) &&
 550             (qlge->flt.header.version != 0)) {
 551                 cmn_err(CE_WARN, "%s(%d) 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
 654 ql_flash_desc(qlge_t *qlge)
 655 {
 656         uint8_t w8;
 657         uint32_t cnt, addr;
 658         uint16_t chksum, *bp, data;
 659         int rval;
 660 
 661         addr = qlge->flash_fdt_addr;
 662 
 663         rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->fdesc,
 664             sizeof (flash_desc_t), addr);
 665         if (rval != DDI_SUCCESS) {
 666                 cmn_err(CE_WARN, "%s(%d) read Flash Descriptor Table error",
 667                     __func__, qlge->instance);
 668                 bzero(&qlge->fdesc, sizeof (flash_desc_t));
 669                 return (rval);
 670         }
 671 
 672         chksum = 0;
 673         data = 0;
 674         bp = (uint16_t *)&qlge->fdesc;
 675         for (cnt = 0; cnt < (sizeof (flash_desc_t)) / 2; cnt++) {
 676                 data = *bp;
 677                 LITTLE_ENDIAN_16(&data);
 678                 chksum += data;
 679                 bp++;
 680         }
 681         /* endian adjustment */
 682         LITTLE_ENDIAN_32(&qlge->fdesc.flash_valid);
 683         LITTLE_ENDIAN_16(&qlge->fdesc.flash_version);
 684         LITTLE_ENDIAN_16(&qlge->fdesc.flash_len);
 685         LITTLE_ENDIAN_16(&qlge->fdesc.flash_checksum);
 686         LITTLE_ENDIAN_16(&qlge->fdesc.flash_unused);
 687         LITTLE_ENDIAN_16(&qlge->fdesc.flash_manuf);
 688         LITTLE_ENDIAN_16(&qlge->fdesc.flash_id);
 689         LITTLE_ENDIAN_32(&qlge->fdesc.block_size);
 690         LITTLE_ENDIAN_32(&qlge->fdesc.alt_block_size);
 691         LITTLE_ENDIAN_32(&qlge->fdesc.flash_size);
 692         LITTLE_ENDIAN_32(&qlge->fdesc.write_enable_data);
 693         LITTLE_ENDIAN_32(&qlge->fdesc.read_timeout);
 694 
 695         /* flash size in desc table is in 1024 bytes */
 696         QL_PRINT(DBG_FLASH, ("flash_valid=%xh\n", qlge->fdesc.flash_valid));
 697         QL_PRINT(DBG_FLASH, ("flash_version=%xh\n", qlge->fdesc.flash_version));
 698         QL_PRINT(DBG_FLASH, ("flash_len=%xh\n", qlge->fdesc.flash_len));
 699         QL_PRINT(DBG_FLASH, ("flash_checksum=%xh\n",
 700             qlge->fdesc.flash_checksum));
 701 
 702         w8 = qlge->fdesc.flash_model[15];
 703         qlge->fdesc.flash_model[15] = 0;
 704         QL_PRINT(DBG_FLASH, ("flash_model=%s\n", qlge->fdesc.flash_model));
 705         qlge->fdesc.flash_model[15] = w8;
 706         QL_PRINT(DBG_FLASH, ("flash_size=%xK bytes\n", qlge->fdesc.flash_size));
 707         qlge->fdesc.flash_size = qlge->fdesc.flash_size * 0x400;
 708         qlge->flash_info.flash_size = qlge->fdesc.flash_size;
 709 
 710         if (chksum != 0 || qlge->fdesc.flash_valid != FLASH_DESC_VAILD ||
 711             qlge->fdesc.flash_version != FLASH_DESC_VERSION) {
 712                 cmn_err(CE_WARN, "invalid descriptor table");
 713                 bzero(&qlge->fdesc, sizeof (flash_desc_t));
 714                 return (DDI_FAILURE);
 715         }
 716 
 717         return (DDI_SUCCESS);
 718 }
 719 
 720 /*
 721  * ql_flash_nic_config
 722  * Get flash NIC Configuration table.
 723  */
 724 static int
 725 ql_flash_nic_config(qlge_t *qlge)
 726 {
 727         uint32_t cnt, addr;
 728         uint16_t chksum, *bp, data;
 729         int rval;
 730 
 731         addr = qlge->flash_nic_config_table_addr;
 732 
 733         rval = qlge_dump_fcode(qlge, (uint8_t *)&qlge->nic_config,
 734             sizeof (ql_nic_config_t), addr);
 735 
 736         if (rval != DDI_SUCCESS) {
 737                 cmn_err(CE_WARN, "fail to read nic_cfg image %xh", rval);
 738                 bzero(&qlge->nic_config, sizeof (ql_nic_config_t));
 739                 return (rval);
 740         }
 741 
 742         chksum = 0;
 743         data = 0;
 744         bp = (uint16_t *)&qlge->nic_config;
 745         for (cnt = 0; cnt < (sizeof (ql_nic_config_t)) / 2; cnt++) {
 746                 data = *bp;
 747                 LITTLE_ENDIAN_16(&data);
 748                 chksum += data;
 749                 bp++;
 750         }
 751 
 752         LITTLE_ENDIAN_32(&qlge->nic_config.signature);
 753         LITTLE_ENDIAN_16(&qlge->nic_config.version);
 754         LITTLE_ENDIAN_16(&qlge->nic_config.size);
 755         LITTLE_ENDIAN_16(&qlge->nic_config.checksum);
 756         LITTLE_ENDIAN_16(&qlge->nic_config.total_data_size);
 757         LITTLE_ENDIAN_16(&qlge->nic_config.num_of_entries);
 758         LITTLE_ENDIAN_16(&qlge->nic_config.vlan_id);
 759         LITTLE_ENDIAN_16(&qlge->nic_config.last_entry);
 760         LITTLE_ENDIAN_16(&qlge->nic_config.subsys_vendor_id);
 761         LITTLE_ENDIAN_16(&qlge->nic_config.subsys_device_id);
 762 
 763         QL_PRINT(DBG_FLASH, ("(%d): signature=%xh\n",
 764             qlge->instance, qlge->nic_config.signature));
 765         QL_PRINT(DBG_FLASH, ("(%d): size=%xh\n",
 766             qlge->instance, qlge->nic_config.size));
 767         QL_PRINT(DBG_FLASH, ("(%d): checksum=%xh\n",
 768             qlge->instance, qlge->nic_config.checksum));
 769         QL_PRINT(DBG_FLASH, ("(%d): version=%xh\n",
 770             qlge->instance, qlge->nic_config.version));
 771         QL_PRINT(DBG_FLASH, ("(%d): total_data_size=%xh\n",
 772             qlge->instance, qlge->nic_config.total_data_size));
 773         QL_PRINT(DBG_FLASH, ("(%d): num_of_entries=%xh\n",
 774             qlge->instance, qlge->nic_config.num_of_entries));
 775         QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
 776             qlge->instance, qlge->nic_config.factory_data_type));
 777         QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
 778             qlge->instance, qlge->nic_config.factory_data_type_size));
 779         QL_PRINT(DBG_FLASH,
 780             ("(%d): factory mac=%02x %02x %02x %02x %02x %02x h\n",
 781             qlge->instance,
 782             qlge->nic_config.factory_MAC[0],
 783             qlge->nic_config.factory_MAC[1],
 784             qlge->nic_config.factory_MAC[2],
 785             qlge->nic_config.factory_MAC[3],
 786             qlge->nic_config.factory_MAC[4],
 787             qlge->nic_config.factory_MAC[5]));
 788 
 789         QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
 790             qlge->instance, qlge->nic_config.clp_data_type));
 791         QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
 792             qlge->instance, qlge->nic_config.clp_data_type_size));
 793         QL_PRINT(DBG_FLASH, ("(%d): clp mac=%x %x %x %x %x %x h\n",
 794             qlge->instance,
 795             qlge->nic_config.clp_MAC[0],
 796             qlge->nic_config.clp_MAC[1],
 797             qlge->nic_config.clp_MAC[2],
 798             qlge->nic_config.clp_MAC[3],
 799             qlge->nic_config.clp_MAC[4],
 800             qlge->nic_config.clp_MAC[5]));
 801 
 802         QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
 803             qlge->instance, qlge->nic_config.clp_vlan_data_type));
 804         QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
 805             qlge->instance, qlge->nic_config.clp_vlan_data_type_size));
 806         QL_PRINT(DBG_FLASH, ("(%d): vlan_id=%xh\n",
 807             qlge->instance, qlge->nic_config.vlan_id));
 808 
 809         QL_PRINT(DBG_FLASH, ("(%d): data_type=%xh\n",
 810             qlge->instance, qlge->nic_config.last_data_type));
 811         QL_PRINT(DBG_FLASH, ("(%d): data_type_size=%xh\n",
 812             qlge->instance, qlge->nic_config.last_data_type_size));
 813         QL_PRINT(DBG_FLASH, ("(%d): last_entry=%xh\n",
 814             qlge->instance, qlge->nic_config.last_entry));
 815 
 816         QL_PRINT(DBG_FLASH, ("(%d): subsys_vendor_id=%xh\n",
 817             qlge->instance, qlge->nic_config.subsys_vendor_id));
 818         QL_PRINT(DBG_FLASH, ("(%d): subsys_device_id=%xh\n",
 819             qlge->instance, qlge->nic_config.subsys_device_id));
 820 
 821         if (chksum != 0 || qlge->nic_config.signature !=
 822             FLASH_NIC_CONFIG_SIGNATURE || qlge->nic_config.version != 1) {
 823                 cmn_err(CE_WARN,
 824                     "invalid flash nic configuration table: chksum %x, "
 825                     "signature %x, version %x",
 826                     chksum, qlge->nic_config.signature,
 827                     qlge->nic_config.version);
 828                 return (DDI_FAILURE);
 829         }
 830 
 831         return (DDI_SUCCESS);
 832 }
 833 
 834 int
 835 ql_flash_vpd(qlge_t *qlge, uint8_t *buf)
 836 {
 837         uint32_t cnt;
 838         uint16_t chksum, *bp, data;
 839         int rval;
 840         uint32_t vpd_size;
 841 
 842         if (buf == NULL) {
 843                 cmn_err(CE_WARN, "%s(%d) buffer is not available.",
 844                     __func__, qlge->instance);
 845                 return (DDI_FAILURE);
 846         }
 847 
 848         if (!qlge->flash_vpd_addr) {
 849                 if (qlge->func_number == qlge->fn0_net)
 850                         qlge->flash_vpd_addr = ISP_8100_VPD0_ADDR;
 851                 else
 852                         qlge->flash_vpd_addr = ISP_8100_VPD1_ADDR;
 853                 vpd_size = ISP_8100_VPD0_SIZE;
 854         }
 855         rval = qlge_dump_fcode(qlge, buf, vpd_size, qlge->flash_vpd_addr);
 856 
 857         if (rval != DDI_SUCCESS) {
 858                 cmn_err(CE_WARN, "%s(%d)read error",
 859                     __func__, qlge->instance);
 860                 bzero(buf, vpd_size);
 861                 return (rval);
 862         }
 863 
 864         QL_DUMP(DBG_FLASH, "flash vpd table raw data:\n", buf, 8, vpd_size);
 865 
 866         chksum = 0;
 867         data = 0;
 868         bp = (uint16_t *)(void *)buf;
 869         for (cnt = 0; cnt < (vpd_size/2); cnt++) {
 870                 data = *bp;
 871                 LITTLE_ENDIAN_16(&data);
 872                 chksum += data;
 873                 bp++;
 874         }
 875         if (chksum != 0) {
 876                 cmn_err(CE_WARN, "%s(%d) invalid flash vpd table",
 877                     __func__, qlge->instance);
 878                 return (DDI_FAILURE);
 879         }
 880         return (DDI_SUCCESS);
 881 }
 882 
 883 int
 884 ql_get_flash_params(qlge_t *qlge)
 885 {
 886         int rval = DDI_SUCCESS;
 887 
 888         /* Get semaphore to access Flash Address and Flash Data Registers */
 889         if (ql_sem_spinlock(qlge, QL_FLASH_SEM_MASK)) {
 890                 rval = DDI_FAILURE;
 891                 goto out;
 892         }
 893         /* do test read of flash ID */
 894         rval = ql_flash_id(qlge);
 895         if (rval != DDI_SUCCESS)
 896                 goto out;
 897 
 898         /*
 899          * Temporarily set the fdesc.flash_size to
 900          * 4M flash size to avoid failing of ql_dump_focde.
 901          */
 902         qlge->fdesc.flash_size = 4096 * 1024; /* ie. 4M bytes */
 903 
 904         /* Default flash descriptor table. */
 905         qlge->fdesc.write_statusreg_cmd = 1;
 906         qlge->fdesc.write_enable_bits = 0;
 907         qlge->fdesc.unprotect_sector_cmd = 0;
 908         qlge->fdesc.protect_sector_cmd = 0;
 909         qlge->fdesc.write_disable_bits = 0x9c;
 910         qlge->fdesc.block_size = 0x10000;
 911         qlge->fdesc.erase_cmd = 0xd8;
 912 
 913         /* ! todo : should read from fltds! */
 914         /* !ql_get_flash_params(qlge); */
 915         qlge->fltds.flt_addr_hi = 0x36;
 916         qlge->fltds.flt_addr_lo = 0x1000;
 917         /* read all other tables from Flash memory */
 918         if (ql_flash_flt(qlge) != DDI_SUCCESS) {
 919                 if (CFG_IST(qlge, CFG_CHIP_8100)) {
 920                         qlge->flash_fdt_addr = ISP_8100_FDT_ADDR; /* 0x360000 */
 921                         if (qlge->func_number == qlge->fn0_net)
 922                                 /* 0x140200 */
 923                                 qlge->flash_nic_config_table_addr =
 924                                     ISP_8100_NIC_PARAM0_ADDR;
 925                         else
 926                                 /* 0x140600 */
 927                                 qlge->flash_nic_config_table_addr =
 928                                     ISP_8100_NIC_PARAM1_ADDR;
 929                 }
 930         }
 931         (void) ql_flash_desc(qlge);
 932         (void) ql_flash_nic_config(qlge);
 933 
 934 out:
 935         ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
 936 
 937         return (rval);
 938 }
 939 
 940 /*
 941  * ql_setup_flash
 942  * Gets the manufacturer and id number of the flash chip,
 943  * and sets up the size parameter.
 944  */
 945 int
 946 ql_setup_flash(qlge_t *qlge)
 947 {
 948         int rval = DDI_SUCCESS;
 949 
 950         if (qlge->flash_fltds_addr != 0) {
 951                 return (rval);
 952         }
 953         if (ql_sem_spinlock(qlge, QL_FLASH_SEM_MASK)) {
 954                 rval = DDI_FAILURE;
 955                 goto out;
 956         }
 957         /* try reading flash ID */
 958         rval = ql_flash_id(qlge);
 959         if (rval != DDI_SUCCESS)
 960                 goto out;
 961 
 962         /* Default flash descriptor table. */
 963         qlge->fdesc.write_statusreg_cmd = 1;
 964         qlge->fdesc.write_enable_bits = 0;
 965         qlge->fdesc.unprotect_sector_cmd = 0;
 966         qlge->fdesc.protect_sector_cmd = 0;
 967         qlge->fdesc.write_disable_bits = 0x9c;
 968         qlge->fdesc.block_size = 0x10000;
 969         qlge->fdesc.erase_cmd = 0xd8;
 970         /* 1 Get the location of Flash Layout Table Data Structure (FLTDS) */
 971         if (ql_find_flash_layout_table_data_structure_addr(qlge)
 972             == DDI_SUCCESS) {
 973                 /* 2,read fltds */
 974                 if (ql_flash_fltds(qlge) == DDI_SUCCESS) {
 975                         /*
 976                          * 3,search for flash descriptor table (FDT)
 977                          * and Nic Configuration Table indices
 978                          */
 979                         if ((qlge->flash_fdt_addr == 0) ||
 980                             (qlge->flash_nic_config_table_addr == 0)) {
 981                                 rval = ql_flash_flt(qlge);
 982                                 if (rval == DDI_SUCCESS) {
 983                                         (void) ql_flash_desc(qlge);
 984                                         (void) ql_flash_nic_config(qlge);
 985                                 } else {
 986                                         rval = DDI_FAILURE;
 987                                         goto out;
 988                                 }
 989                         }
 990                 } else {
 991                         rval = DDI_FAILURE;
 992                         goto out;
 993                 }
 994         } else {
 995                 rval = DDI_FAILURE;
 996                 goto out;
 997         }
 998 out:
 999         ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
1000 
1001         return (rval);
1002 
1003 }
1004 
1005 /*
1006  * ql_change_endian
1007  * Change endianess of byte array.
1008  */
1009 void
1010 ql_change_endian(uint8_t buf[], size_t size)
1011 {
1012         uint8_t byte;
1013         size_t cnt1;
1014         size_t cnt;
1015 
1016         cnt1 = size - 1;
1017         for (cnt = 0; cnt < size / 2; cnt++) {
1018                 byte = buf[cnt1];
1019                 buf[cnt1] = buf[cnt];
1020                 buf[cnt] = byte;
1021                 cnt1--;
1022         }
1023 }
1024 
1025 static int
1026 ql_wait_flash_reg_ready(qlge_t *qlge, uint32_t wait_bit)
1027 {
1028         uint32_t reg_status;
1029         int rtn_val = DDI_SUCCESS;
1030         uint32_t delay = 300000;
1031 
1032         do {
1033                 reg_status = ql_read_reg(qlge, REG_FLASH_ADDRESS);
1034                 if (reg_status & FLASH_ERR_FLAG) {
1035                         cmn_err(CE_WARN,
1036                             "%s(%d) flash address register error bit set!",
1037                             __func__, qlge->instance);
1038                         rtn_val = DDI_FAILURE;
1039                         break;
1040                 }
1041                 if (reg_status & wait_bit) {
1042                         break;
1043                 }
1044                 drv_usecwait(10);
1045         } while (--delay);
1046 
1047         if (delay == 0) {
1048                 cmn_err(CE_WARN,
1049                     "%s(%d) timeout error!", __func__, qlge->instance);
1050                 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
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
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
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
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
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
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
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
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
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
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
1408 ql_sem_flash_unlock(qlge_t *qlge)
1409 {
1410         ql_sem_unlock(qlge, QL_FLASH_SEM_MASK);
1411 }