The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/qlxgbe/ql_misc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2013-2016 Qlogic Corporation
    5  * All rights reserved.
    6  *
    7  *  Redistribution and use in source and binary forms, with or without
    8  *  modification, are permitted provided that the following conditions
    9  *  are met:
   10  *
   11  *  1. Redistributions of source code must retain the above copyright
   12  *     notice, this list of conditions and the following disclaimer.
   13  *  2. Redistributions in binary form must reproduce the above copyright
   14  *     notice, this list of conditions and the following disclaimer in the
   15  *     documentation and/or other materials provided with the distribution.
   16  *
   17  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   18  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   21  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   22  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   23  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   24  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   25  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   26  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   27  *  POSSIBILITY OF SUCH DAMAGE.
   28  */
   29 /*
   30  * File : ql_misc.c
   31  * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD$");
   36 
   37 #include "ql_os.h"
   38 #include "ql_hw.h"
   39 #include "ql_def.h"
   40 #include "ql_inline.h"
   41 #include "ql_glbl.h"
   42 #include "ql_dbg.h"
   43 #include "ql_tmplt.h"
   44 
   45 #define QL_FDT_OFFSET           0x3F0000
   46 #define Q8_FLASH_SECTOR_SIZE    0x10000
   47 
   48 static int qla_ld_fw_init(qla_host_t *ha);
   49 
   50 /*
   51  * structure encapsulating the value to read/write to offchip memory
   52  */
   53 typedef struct _offchip_mem_val {
   54         uint32_t data_lo;
   55         uint32_t data_hi;
   56         uint32_t data_ulo;
   57         uint32_t data_uhi;
   58 } offchip_mem_val_t;
   59 
   60 /*
   61  * Name: ql_rdwr_indreg32
   62  * Function: Read/Write an Indirect Register
   63  */
   64 int
   65 ql_rdwr_indreg32(qla_host_t *ha, uint32_t addr, uint32_t *val, uint32_t rd)
   66 {
   67         uint32_t wnd_reg;
   68         uint32_t count = 100;
   69 
   70         wnd_reg = (Q8_CRB_WINDOW_PF0 | (ha->pci_func << 2));
   71 
   72         WRITE_REG32(ha, wnd_reg, addr);
   73 
   74         while (count--) {
   75                 if (READ_REG32(ha, wnd_reg) == addr)
   76                         break;
   77                 qla_mdelay(__func__, 1);
   78         }
   79         if (!count || QL_ERR_INJECT(ha, INJCT_RDWR_INDREG_FAILURE)) {
   80                 device_printf(ha->pci_dev, "%s: [0x%08x, 0x%08x, %d] failed\n",
   81                         __func__, addr, *val, rd);
   82                 QL_INITIATE_RECOVERY(ha);
   83                 return -1;
   84         }
   85 
   86         if (rd) {
   87                 *val = READ_REG32(ha, Q8_WILD_CARD);
   88         } else {
   89                 WRITE_REG32(ha, Q8_WILD_CARD, *val);
   90         }
   91 
   92         return 0;
   93 }
   94 
   95 /*
   96  * Name: ql_rdwr_offchip_mem
   97  * Function: Read/Write OffChip Memory
   98  */
   99 int
  100 ql_rdwr_offchip_mem(qla_host_t *ha, uint64_t addr, q80_offchip_mem_val_t *val,
  101         uint32_t rd)
  102 {
  103         uint32_t count = 100;
  104         uint32_t data, step = 0;
  105 
  106         if (QL_ERR_INJECT(ha, INJCT_RDWR_OFFCHIPMEM_FAILURE))
  107                 goto exit_ql_rdwr_offchip_mem;
  108 
  109         data = (uint32_t)addr;
  110         if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_LO, &data, 0)) {
  111                 step = 1;
  112                 goto exit_ql_rdwr_offchip_mem;
  113         }
  114 
  115         data = (uint32_t)(addr >> 32);
  116         if (ql_rdwr_indreg32(ha, Q8_MS_ADDR_HI, &data, 0)) {
  117                 step = 2;
  118                 goto exit_ql_rdwr_offchip_mem;
  119         }
  120 
  121         data = BIT_1;
  122         if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
  123                 step = 3;
  124                 goto exit_ql_rdwr_offchip_mem;
  125         }
  126 
  127         if (!rd) {
  128                 data = val->data_lo;
  129                 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_0_31, &data, 0)) {
  130                         step = 4;
  131                         goto exit_ql_rdwr_offchip_mem;
  132                 }
  133 
  134                 data = val->data_hi;
  135                 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_32_63, &data, 0)) {
  136                         step = 5;
  137                         goto exit_ql_rdwr_offchip_mem;
  138                 }
  139 
  140                 data = val->data_ulo;
  141                 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_64_95, &data, 0)) {
  142                         step = 6;
  143                         goto exit_ql_rdwr_offchip_mem;
  144                 }
  145 
  146                 data = val->data_uhi;
  147                 if (ql_rdwr_indreg32(ha, Q8_MS_WR_DATA_96_127, &data, 0)) {
  148                         step = 7;
  149                         goto exit_ql_rdwr_offchip_mem;
  150                 }
  151 
  152                 data = (BIT_2|BIT_1|BIT_0);
  153                 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
  154                         step = 7;
  155                         goto exit_ql_rdwr_offchip_mem;
  156                 }
  157         } else {
  158                 data = (BIT_1|BIT_0);
  159                 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 0)) {
  160                         step = 8;
  161                         goto exit_ql_rdwr_offchip_mem;
  162                 }
  163         }
  164 
  165         while (count--) {
  166                 if (ql_rdwr_indreg32(ha, Q8_MS_CNTRL, &data, 1)) {
  167                         step = 9;
  168                         goto exit_ql_rdwr_offchip_mem;
  169                 }
  170 
  171                 if (!(data & BIT_3)) {
  172                         if (rd) {
  173                                 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_0_31,
  174                                         &data, 1)) {
  175                                         step = 10;
  176                                         goto exit_ql_rdwr_offchip_mem;
  177                                 }
  178                                 val->data_lo = data;
  179 
  180                                 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_32_63,
  181                                         &data, 1)) {
  182                                         step = 11;
  183                                         goto exit_ql_rdwr_offchip_mem;
  184                                 }
  185                                 val->data_hi = data;
  186 
  187                                 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_64_95,
  188                                         &data, 1)) {
  189                                         step = 12;
  190                                         goto exit_ql_rdwr_offchip_mem;
  191                                 }
  192                                 val->data_ulo = data;
  193 
  194                                 if (ql_rdwr_indreg32(ha, Q8_MS_RD_DATA_96_127,
  195                                         &data, 1)) {
  196                                         step = 13;
  197                                         goto exit_ql_rdwr_offchip_mem;
  198                                 }
  199                                 val->data_uhi = data;
  200                         }
  201                         return 0;
  202                 } else 
  203                         qla_mdelay(__func__, 1);
  204         }
  205 
  206 exit_ql_rdwr_offchip_mem:
  207 
  208         device_printf(ha->pci_dev,
  209                 "%s: [0x%08x 0x%08x : 0x%08x 0x%08x 0x%08x 0x%08x]"
  210                 " [%d] [%d] failed\n", __func__, (uint32_t)(addr >> 32),
  211                 (uint32_t)(addr), val->data_lo, val->data_hi, val->data_ulo,
  212                 val->data_uhi, rd, step);
  213 
  214         QL_INITIATE_RECOVERY(ha);
  215 
  216         return (-1);
  217 }
  218 
  219 /*
  220  * Name: ql_rd_flash32
  221  * Function: Read Flash Memory
  222  */
  223 int
  224 ql_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data)
  225 {
  226         uint32_t data32;
  227 
  228         if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 0xABCDABCD)) {
  229                 device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
  230                         __func__);
  231                 return (-1);
  232         }
  233 
  234         data32 = addr;
  235         if (ql_rdwr_indreg32(ha, Q8_FLASH_DIRECT_WINDOW, &data32, 0)) {
  236                 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  237                 device_printf(ha->pci_dev,
  238                         "%s: Q8_FLASH_DIRECT_WINDOW[0x%08x] failed\n",
  239                         __func__, data32);
  240                 return (-1);
  241         }
  242 
  243         data32 = Q8_FLASH_DIRECT_DATA | (addr & 0xFFFF);
  244         if (ql_rdwr_indreg32(ha, data32, data, 1)) {
  245                 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  246                 device_printf(ha->pci_dev,
  247                         "%s: data32:data [0x%08x] failed\n",
  248                         __func__, data32);
  249                 return (-1);
  250         }
  251 
  252         qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  253         return 0;
  254 }
  255 
  256 static int 
  257 qla_get_fdt(qla_host_t *ha)
  258 {
  259         uint32_t data32;
  260         int count;
  261         qla_hw_t *hw;
  262 
  263         hw = &ha->hw;
  264 
  265         for (count = 0; count < sizeof(qla_flash_desc_table_t); count+=4) {
  266                 if (ql_rd_flash32(ha, QL_FDT_OFFSET + count, 
  267                         (uint32_t *)&hw->fdt + (count >> 2))) {
  268                                 device_printf(ha->pci_dev,
  269                                         "%s: Read QL_FDT_OFFSET + %d failed\n",
  270                                         __func__, count);
  271                                 return (-1);
  272                 }
  273         }
  274 
  275         if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 
  276                 Q8_FDT_LOCK_MAGIC_ID)) {
  277                 device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
  278                         __func__);
  279                 return (-1);
  280         }
  281 
  282         data32 = Q8_FDT_FLASH_ADDR_VAL;
  283         if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
  284                 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  285                 device_printf(ha->pci_dev,
  286                         "%s: Write to Q8_FLASH_ADDRESS failed\n",
  287                         __func__);
  288                 return (-1);
  289         }
  290 
  291         data32 = Q8_FDT_FLASH_CTRL_VAL;
  292         if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
  293                 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  294                 device_printf(ha->pci_dev,
  295                         "%s: Write to Q8_FLASH_CONTROL failed\n",
  296                         __func__);
  297                 return (-1);
  298         }
  299 
  300         count = 0;
  301 
  302         do {
  303                 if (count < 1000) {
  304                         QLA_USEC_DELAY(10);
  305                         count += 10;
  306                 } else {
  307                         qla_mdelay(__func__, 1);
  308                         count += 1000;
  309                 }
  310 
  311                 data32 = 0;
  312 
  313                 if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
  314                         qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  315                         device_printf(ha->pci_dev,
  316                                 "%s: Read Q8_FLASH_STATUS failed\n",
  317                                 __func__);
  318                         return (-1);
  319                 }
  320 
  321                 data32 &= 0x6;
  322 
  323         } while ((count < 10000) && (data32 != 0x6));
  324 
  325         if (data32 != 0x6) {
  326                 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  327                 device_printf(ha->pci_dev,
  328                         "%s: Poll Q8_FLASH_STATUS failed\n",
  329                         __func__);
  330                 return (-1);
  331         }
  332 
  333         if (ql_rdwr_indreg32(ha, Q8_FLASH_RD_DATA, &data32, 1)) {
  334                 qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  335                 device_printf(ha->pci_dev,
  336                         "%s: Read Q8_FLASH_RD_DATA failed\n",
  337                         __func__);
  338                 return (-1);
  339         }
  340 
  341         qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  342 
  343         data32 &= Q8_FDT_MASK_VAL;
  344         if (hw->fdt.flash_manuf == data32)
  345                 return (0);
  346         else
  347                 return (-1);
  348 }
  349 
  350 static int
  351 qla_flash_write_enable(qla_host_t *ha, int enable)
  352 {
  353         uint32_t data32;
  354         int count = 0;
  355 
  356         data32 = Q8_WR_ENABLE_FL_ADDR | ha->hw.fdt.write_statusreg_cmd; 
  357         if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
  358                 device_printf(ha->pci_dev,
  359                         "%s: Write to Q8_FLASH_ADDRESS failed\n",
  360                         __func__);
  361                 return (-1);
  362         }
  363 
  364         if (enable)
  365                 data32 = ha->hw.fdt.write_enable_bits;
  366         else
  367                 data32 = ha->hw.fdt.write_disable_bits;
  368 
  369         if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, &data32, 0)) {
  370                 device_printf(ha->pci_dev,
  371                         "%s: Write to Q8_FLASH_WR_DATA failed\n",
  372                         __func__);
  373                 return (-1);
  374         }
  375 
  376         data32 = Q8_WR_ENABLE_FL_CTRL;
  377         if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
  378                 device_printf(ha->pci_dev,
  379                         "%s: Write to Q8_FLASH_CONTROL failed\n",
  380                         __func__);
  381                 return (-1);
  382         }
  383 
  384         do {
  385                 if (count < 1000) {
  386                         QLA_USEC_DELAY(10);
  387                         count += 10;
  388                 } else {
  389                         qla_mdelay(__func__, 1);
  390                         count += 1000;
  391                 }
  392 
  393                 data32 = 0;
  394                 if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
  395                         device_printf(ha->pci_dev,
  396                                 "%s: Read Q8_FLASH_STATUS failed\n",
  397                                 __func__);
  398                         return (-1);
  399                 }
  400 
  401                 data32 &= 0x6;
  402 
  403         } while ((count < 10000) && (data32 != 0x6));
  404                         
  405         if (data32 != 0x6) {
  406                 device_printf(ha->pci_dev,
  407                         "%s: Poll Q8_FLASH_STATUS failed\n",
  408                         __func__);
  409                 return (-1);
  410         }
  411 
  412         return 0;
  413 }
  414 
  415 static int
  416 qla_erase_flash_sector(qla_host_t *ha, uint32_t start)
  417 {
  418         uint32_t data32;
  419         int count = 0;
  420 
  421         do {
  422                 qla_mdelay(__func__, 1);
  423 
  424                 data32 = 0;
  425                 if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) { 
  426                         device_printf(ha->pci_dev,
  427                                 "%s: Read Q8_FLASH_STATUS failed\n",
  428                                 __func__);
  429                         return (-1);
  430                 }
  431 
  432                 data32 &= 0x6;
  433 
  434         } while (((count++) < 1000) && (data32 != 0x6));
  435 
  436         if (data32 != 0x6) {
  437                 device_printf(ha->pci_dev,
  438                         "%s: Poll Q8_FLASH_STATUS failed\n",
  439                         __func__);
  440                 return (-1);
  441         }
  442 
  443         data32 = (start >> 16) & 0xFF;
  444         if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, &data32, 0)) { 
  445                 device_printf(ha->pci_dev,
  446                         "%s: Write to Q8_FLASH_WR_DATA failed\n",
  447                         __func__);
  448                 return (-1);
  449         }
  450 
  451         data32 = Q8_ERASE_FL_ADDR_MASK | ha->hw.fdt.erase_cmd;
  452         if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
  453                 device_printf(ha->pci_dev,
  454                         "%s: Write to Q8_FLASH_ADDRESS failed\n",
  455                         __func__);
  456                 return (-1);
  457         }
  458 
  459         data32 = Q8_ERASE_FL_CTRL_MASK;
  460         if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
  461                 device_printf(ha->pci_dev,
  462                         "%s: Write to Q8_FLASH_CONTROL failed\n",
  463                         __func__);
  464                 return (-1);
  465         }
  466 
  467         count = 0;
  468         do {
  469                 qla_mdelay(__func__, 1);
  470 
  471                 data32 = 0;
  472                 if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
  473                         device_printf(ha->pci_dev,
  474                                 "%s: Read Q8_FLASH_STATUS failed\n",
  475                                 __func__);
  476                         return (-1);
  477                 }
  478 
  479                 data32 &= 0x6;
  480 
  481         } while (((count++) < 1000) && (data32 != 0x6));
  482 
  483         if (data32 != 0x6) {
  484                 device_printf(ha->pci_dev,
  485                         "%s: Poll Q8_FLASH_STATUS failed\n",
  486                         __func__);
  487                 return (-1);
  488         }
  489 
  490         return 0;
  491 }
  492 
  493 int
  494 ql_erase_flash(qla_host_t *ha, uint32_t off, uint32_t size)
  495 {
  496         int rval = 0;
  497         uint32_t start;
  498 
  499         if (off & (Q8_FLASH_SECTOR_SIZE -1))
  500                 return (-1);
  501                 
  502         if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 
  503                 Q8_ERASE_LOCK_MAGIC_ID)) {
  504                 device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
  505                         __func__);
  506                 return (-1);
  507         }
  508 
  509         if (qla_flash_write_enable(ha, 1) != 0) {
  510                 rval = -1;
  511                 goto ql_erase_flash_exit;
  512         }
  513 
  514         for (start = off; start < (off + size); start = start + 
  515                 Q8_FLASH_SECTOR_SIZE) {
  516                         if (qla_erase_flash_sector(ha, start)) {
  517                                 rval = -1;
  518                                 break;
  519                         }
  520         }
  521 
  522         rval = qla_flash_write_enable(ha, 0);
  523 
  524 ql_erase_flash_exit:
  525         qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  526         return (rval);
  527 }
  528 
  529 static int
  530 qla_wr_flash32(qla_host_t *ha, uint32_t off, uint32_t *data)
  531 {
  532         uint32_t data32;
  533         int count = 0;
  534 
  535         data32 = Q8_WR_FL_ADDR_MASK | (off >> 2);
  536         if (ql_rdwr_indreg32(ha, Q8_FLASH_ADDRESS, &data32, 0)) {
  537                 device_printf(ha->pci_dev,
  538                         "%s: Write to Q8_FLASH_ADDRESS failed\n",
  539                         __func__);
  540                 return (-1);
  541         }
  542 
  543         if (ql_rdwr_indreg32(ha, Q8_FLASH_WR_DATA, data, 0)) {
  544                 device_printf(ha->pci_dev,
  545                         "%s: Write to Q8_FLASH_WR_DATA failed\n",
  546                         __func__);
  547                 return (-1);
  548         }
  549 
  550         data32 = Q8_WR_FL_CTRL_MASK;
  551         if (ql_rdwr_indreg32(ha, Q8_FLASH_CONTROL, &data32, 0)) {
  552                 device_printf(ha->pci_dev,
  553                         "%s: Write to Q8_FLASH_CONTROL failed\n",
  554                         __func__);
  555                 return (-1);
  556         }
  557 
  558         do {
  559                 if (count < 1000) {
  560                         QLA_USEC_DELAY(10);
  561                         count += 10;
  562                 } else {
  563                         qla_mdelay(__func__, 1);
  564                         count += 1000;
  565                 }
  566 
  567                 data32 = 0;
  568                 if (ql_rdwr_indreg32(ha, Q8_FLASH_STATUS, &data32, 1)) {
  569                         device_printf(ha->pci_dev,
  570                                 "%s: Read Q8_FLASH_STATUS failed\n",
  571                                 __func__);
  572                         return (-1);
  573                 }
  574 
  575                 data32 &= 0x6;
  576 
  577         } while ((count < 10000) && (data32 != 0x6)); 
  578 
  579         if (data32 != 0x6) {
  580                 device_printf(ha->pci_dev,
  581                         "%s: Poll Q8_FLASH_STATUS failed\n",
  582                         __func__);
  583                 return (-1);
  584         }
  585 
  586         return 0;
  587 }
  588 
  589 static int
  590 qla_flash_write_data(qla_host_t *ha, uint32_t off, uint32_t size,
  591         void *data)
  592 {
  593         int rval = 0;
  594         uint32_t start;
  595         uint32_t *data32 = data;
  596 
  597         if (qla_sem_lock(ha, Q8_FLASH_LOCK, Q8_FLASH_LOCK_ID, 
  598                 Q8_WR_FL_LOCK_MAGIC_ID)) {
  599                         device_printf(ha->pci_dev, "%s: Q8_FLASH_LOCK failed\n",
  600                                 __func__);
  601                         rval = -1;
  602                         goto qla_flash_write_data_exit;
  603         }
  604 
  605         if ((qla_flash_write_enable(ha, 1) != 0)) {
  606                 device_printf(ha->pci_dev, "%s: failed\n",
  607                         __func__);
  608                 rval = -1;
  609                 goto qla_flash_write_data_unlock_exit;
  610         }
  611 
  612         for (start = off; start < (off + size); start = start + 4) {
  613                 if (*data32 != 0xFFFFFFFF) {
  614                         if (qla_wr_flash32(ha, start, data32)) {
  615                                 rval = -1;
  616                                 break;
  617                         }
  618                 }
  619                 data32++;
  620         }
  621 
  622         rval = qla_flash_write_enable(ha, 0);
  623 
  624 qla_flash_write_data_unlock_exit:
  625         qla_sem_unlock(ha, Q8_FLASH_UNLOCK);
  626 
  627 qla_flash_write_data_exit:
  628         return (rval);
  629 }
  630 
  631 int
  632 ql_wr_flash_buffer(qla_host_t *ha, uint32_t off, uint32_t size, void *buf) 
  633 {
  634         int rval = 0;
  635         void *data;
  636 
  637         if (size == 0)
  638                 return 0;
  639 
  640         size = size << 2;
  641 
  642         if (buf == NULL) 
  643                 return -1;
  644 
  645         if ((data = malloc(size, M_QLA83XXBUF, M_NOWAIT)) == NULL) {
  646                 device_printf(ha->pci_dev, "%s: malloc failed \n", __func__);
  647                 rval = -1;
  648                 goto ql_wr_flash_buffer_exit;
  649         }
  650 
  651         if ((rval = copyin(buf, data, size))) {
  652                 device_printf(ha->pci_dev, "%s copyin failed\n", __func__);
  653                 goto ql_wr_flash_buffer_free_exit;
  654         }
  655 
  656         rval = qla_flash_write_data(ha, off, size, data);
  657 
  658 ql_wr_flash_buffer_free_exit:
  659         free(data, M_QLA83XXBUF);
  660 
  661 ql_wr_flash_buffer_exit:
  662         return (rval);
  663 }
  664 
  665 #ifdef QL_LDFLASH_FW
  666 /*
  667  * Name: qla_load_fw_from_flash
  668  * Function: Reads the Bootloader from Flash and Loads into Offchip Memory
  669  */
  670 static void
  671 qla_load_fw_from_flash(qla_host_t *ha)
  672 {
  673         uint32_t flash_off      = 0x10000;
  674         uint64_t mem_off;
  675         uint32_t count, mem_size;
  676         q80_offchip_mem_val_t val;
  677 
  678         mem_off = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
  679         mem_size = READ_REG32(ha, Q8_BOOTLD_SIZE);
  680 
  681         device_printf(ha->pci_dev, "%s: [0x%08x][0x%08x]\n",
  682                 __func__, (uint32_t)mem_off, mem_size);
  683 
  684         /* only bootloader needs to be loaded into memory */
  685         for (count = 0; count < mem_size ; ) {
  686                 ql_rd_flash32(ha, flash_off, &val.data_lo);
  687                 count = count + 4;
  688                 flash_off = flash_off + 4;
  689 
  690                 ql_rd_flash32(ha, flash_off, &val.data_hi);
  691                 count = count + 4;
  692                 flash_off = flash_off + 4;
  693 
  694                 ql_rd_flash32(ha, flash_off, &val.data_ulo);
  695                 count = count + 4;
  696                 flash_off = flash_off + 4;
  697 
  698                 ql_rd_flash32(ha, flash_off, &val.data_uhi);
  699                 count = count + 4;
  700                 flash_off = flash_off + 4;
  701 
  702                 ql_rdwr_offchip_mem(ha, mem_off, &val, 0);
  703 
  704                 mem_off = mem_off + 16;
  705         }
  706 
  707         return;
  708 }
  709 #endif /* #ifdef QL_LDFLASH_FW */
  710 
  711 /*
  712  * Name: qla_init_from_flash
  713  * Function: Performs Initialization which consists of the following sequence
  714  *      - reset
  715  *      - CRB Init
  716  *      - Peg Init
  717  *      - Read the Bootloader from Flash and Load into Offchip Memory
  718  *      - Kick start the bootloader which loads the rest of the firmware
  719  *              and performs the remaining steps in the initialization process.
  720  */
  721 static int
  722 qla_init_from_flash(qla_host_t *ha)
  723 {
  724         uint32_t delay = 300;
  725         uint32_t data;
  726 
  727         qla_ld_fw_init(ha);
  728 
  729         do {
  730                 data = READ_REG32(ha, Q8_CMDPEG_STATE);
  731 
  732                 QL_DPRINT2(ha,
  733                         (ha->pci_dev, "%s: func[%d] cmdpegstate 0x%08x\n",
  734                                 __func__, ha->pci_func, data));
  735                 if (data == 0xFF01) {
  736                         QL_DPRINT2(ha, (ha->pci_dev,
  737                                 "%s: func[%d] init complete\n",
  738                                 __func__, ha->pci_func));
  739                         return(0);
  740                 }
  741                 qla_mdelay(__func__, 100);
  742         } while (delay--);
  743 
  744         return (-1);
  745 }
  746 
  747 /*
  748  * Name: ql_init_hw
  749  * Function: Initializes P3+ hardware.
  750  */
  751 int
  752 ql_init_hw(qla_host_t *ha)
  753 {
  754         device_t dev;
  755         int ret = 0;
  756         uint32_t val, delay = 300;
  757 
  758         dev = ha->pci_dev;
  759 
  760         QL_DPRINT1(ha, (dev, "%s: enter\n", __func__));
  761 
  762         if (ha->pci_func & 0x1) {
  763                 while ((ha->pci_func & 0x1) && delay--) {
  764                         val = READ_REG32(ha, Q8_CMDPEG_STATE);
  765 
  766                         if (val == 0xFF01) {
  767                                 QL_DPRINT2(ha, (dev,
  768                                         "%s: func = %d init complete\n",
  769                                         __func__, ha->pci_func));
  770                                 qla_mdelay(__func__, 100);
  771                                 goto qla_init_exit;
  772                         }
  773                         qla_mdelay(__func__, 100);
  774                 }
  775                 ret = -1;
  776                 goto ql_init_hw_exit;
  777         }
  778 
  779         val = READ_REG32(ha, Q8_CMDPEG_STATE);
  780         if (!cold || (val != 0xFF01) || ha->qla_initiate_recovery) {
  781                 ret = qla_init_from_flash(ha);
  782                 qla_mdelay(__func__, 100);
  783         }
  784 
  785 qla_init_exit:
  786         ha->fw_ver_major = READ_REG32(ha, Q8_FW_VER_MAJOR);
  787         ha->fw_ver_minor = READ_REG32(ha, Q8_FW_VER_MINOR);
  788         ha->fw_ver_sub = READ_REG32(ha, Q8_FW_VER_SUB);
  789 
  790         if (qla_get_fdt(ha) != 0) {
  791                 device_printf(dev, "%s: qla_get_fdt failed\n", __func__);
  792         } else {
  793                 ha->hw.flags.fdt_valid = 1;
  794         }
  795 
  796 ql_init_hw_exit:
  797 
  798         if (ret) {
  799                 if (ha->hw.sp_log_stop_events & Q8_SP_LOG_STOP_HW_INIT_FAILURE)
  800                         ha->hw.sp_log_stop = -1;
  801         }
  802 
  803         return (ret);
  804 }
  805 
  806 void
  807 ql_read_mac_addr(qla_host_t *ha)
  808 {
  809         uint8_t *macp;
  810         uint32_t mac_lo;
  811         uint32_t mac_hi;
  812         uint32_t flash_off;
  813 
  814         flash_off = Q8_BOARD_CONFIG_OFFSET + Q8_BOARD_CONFIG_MAC0_LO +
  815                         (ha->pci_func << 3);
  816         ql_rd_flash32(ha, flash_off, &mac_lo);
  817 
  818         flash_off += 4;
  819         ql_rd_flash32(ha, flash_off, &mac_hi);
  820 
  821         macp = (uint8_t *)&mac_lo;
  822         ha->hw.mac_addr[5] = macp[0];
  823         ha->hw.mac_addr[4] = macp[1];
  824         ha->hw.mac_addr[3] = macp[2];
  825         ha->hw.mac_addr[2] = macp[3];
  826 
  827         macp = (uint8_t *)&mac_hi;
  828         ha->hw.mac_addr[1] = macp[0];
  829         ha->hw.mac_addr[0] = macp[1];
  830 
  831         //device_printf(ha->pci_dev, "%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
  832         //      __func__, ha->hw.mac_addr[0], ha->hw.mac_addr[1],
  833         //      ha->hw.mac_addr[2], ha->hw.mac_addr[3],
  834         //      ha->hw.mac_addr[4], ha->hw.mac_addr[5]);
  835 
  836         return;
  837 }
  838 
  839 /*
  840  * Stop/Start/Initialization Handling
  841  */
  842 
  843 static uint16_t
  844 qla_tmplt_16bit_checksum(qla_host_t *ha, uint16_t *buf, uint32_t size)
  845 {
  846         uint32_t sum = 0;
  847         uint32_t count = size >> 1; /* size in 16 bit words */
  848 
  849         while (count-- > 0) 
  850                 sum += *buf++;
  851 
  852         while (sum >> 16) 
  853                 sum = (sum & 0xFFFF) + (sum >> 16);
  854 
  855         return (~sum);
  856 }
  857 
  858 static int
  859 qla_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
  860 {
  861         q8_wrl_e_t *wr_l;
  862         int i;
  863 
  864         wr_l = (q8_wrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
  865 
  866         for (i = 0; i < ce_hdr->opcount; i++, wr_l++) {
  867                 if (ql_rdwr_indreg32(ha, wr_l->addr, &wr_l->value, 0)) {
  868                         device_printf(ha->pci_dev,
  869                                 "%s: [0x%08x 0x%08x] error\n", __func__,
  870                                 wr_l->addr, wr_l->value);
  871                         return -1;
  872                 }
  873                 if (ce_hdr->delay_to) {
  874                         DELAY(ce_hdr->delay_to);
  875                 }
  876         }
  877         return 0;
  878 }
  879 
  880 static int
  881 qla_rd_wr_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
  882 {
  883         q8_rdwrl_e_t *rd_wr_l;
  884         uint32_t data;
  885         int i;
  886 
  887         rd_wr_l = (q8_rdwrl_e_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
  888 
  889         for (i = 0; i < ce_hdr->opcount; i++, rd_wr_l++) {
  890                 if (ql_rdwr_indreg32(ha, rd_wr_l->rd_addr, &data, 1)) {
  891                         device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
  892                                 __func__, rd_wr_l->rd_addr);
  893 
  894                         return -1;
  895                 }
  896 
  897                 if (ql_rdwr_indreg32(ha, rd_wr_l->wr_addr, &data, 0)) {
  898                         device_printf(ha->pci_dev,
  899                                 "%s: [0x%08x 0x%08x] error\n", __func__,
  900                                 rd_wr_l->wr_addr, data);
  901                         return -1;
  902                 }
  903                 if (ce_hdr->delay_to) {
  904                         DELAY(ce_hdr->delay_to);
  905                 }
  906         }
  907         return 0;
  908 }
  909 
  910 static int
  911 qla_poll_reg(qla_host_t *ha, uint32_t addr, uint32_t ms_to, uint32_t tmask,
  912         uint32_t tvalue)
  913 {
  914         uint32_t data;
  915 
  916         while (ms_to) {
  917                 if (ql_rdwr_indreg32(ha, addr, &data, 1)) {
  918                         device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
  919                                 __func__, addr);
  920                         return -1;
  921                 }
  922 
  923                 if ((data & tmask) != tvalue) {
  924                         ms_to--;
  925                 } else 
  926                         break;
  927 
  928                 qla_mdelay(__func__, 1);
  929         }
  930         return ((ms_to ? 0: -1));
  931 }
  932 
  933 static int
  934 qla_poll_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
  935 {
  936         int             i;
  937         q8_poll_hdr_t   *phdr;
  938         q8_poll_e_t     *pe;
  939         uint32_t        data;
  940 
  941         phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
  942         pe = (q8_poll_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
  943 
  944         for (i = 0; i < ce_hdr->opcount; i++, pe++) {
  945                 if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
  946                         device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
  947                                 __func__, pe->addr);
  948                         return -1;
  949                 }
  950 
  951                 if (ce_hdr->delay_to)  {
  952                         if ((data & phdr->tmask) == phdr->tvalue)
  953                                 break;
  954                         if (qla_poll_reg(ha, pe->addr, ce_hdr->delay_to,
  955                                 phdr->tmask, phdr->tvalue)) {
  956                                 if (ql_rdwr_indreg32(ha, pe->to_addr, &data,
  957                                         1)) {
  958                                         device_printf(ha->pci_dev,
  959                                                 "%s: [0x%08x] error\n",
  960                                                 __func__, pe->to_addr);
  961                                         return -1;
  962                                 }
  963 
  964                                 if (ql_rdwr_indreg32(ha, pe->addr, &data, 1)) {
  965                                         device_printf(ha->pci_dev,
  966                                                 "%s: [0x%08x] error\n",
  967                                                 __func__, pe->addr);
  968                                         return -1;
  969                                 }
  970                         }
  971                 }
  972         }
  973         return 0;
  974 }
  975 
  976 static int
  977 qla_poll_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
  978 {
  979         int             i;
  980         q8_poll_hdr_t   *phdr;
  981         q8_poll_wr_e_t  *wr_e;
  982 
  983         phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
  984         wr_e = (q8_poll_wr_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
  985 
  986         for (i = 0; i < ce_hdr->opcount; i++, wr_e++) {
  987                 if (ql_rdwr_indreg32(ha, wr_e->dr_addr, &wr_e->dr_value, 0)) {
  988                         device_printf(ha->pci_dev,
  989                                 "%s: [0x%08x 0x%08x] error\n", __func__,
  990                                 wr_e->dr_addr, wr_e->dr_value);
  991                         return -1;
  992                 }
  993                 if (ql_rdwr_indreg32(ha, wr_e->ar_addr, &wr_e->ar_value, 0)) {
  994                         device_printf(ha->pci_dev,
  995                                 "%s: [0x%08x 0x%08x] error\n", __func__,
  996                                 wr_e->ar_addr, wr_e->ar_value);
  997                         return -1;
  998                 }
  999                 if (ce_hdr->delay_to)  {
 1000                         if (qla_poll_reg(ha, wr_e->ar_addr, ce_hdr->delay_to,
 1001                                 phdr->tmask, phdr->tvalue))
 1002                                 device_printf(ha->pci_dev, "%s: "
 1003                                         "[ar_addr, ar_value, delay, tmask,"
 1004                                         "tvalue] [0x%08x 0x%08x 0x%08x 0x%08x"
 1005                                         " 0x%08x]\n",
 1006                                         __func__, wr_e->ar_addr, wr_e->ar_value,
 1007                                         ce_hdr->delay_to, phdr->tmask,
 1008                                         phdr->tvalue);
 1009                 }
 1010         }
 1011         return 0;
 1012 }
 1013 
 1014 static int
 1015 qla_poll_read_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
 1016 {
 1017         int             i;
 1018         q8_poll_hdr_t   *phdr;
 1019         q8_poll_rd_e_t  *rd_e;
 1020         uint32_t        value;
 1021 
 1022         phdr = (q8_poll_hdr_t *)((uint8_t *)ce_hdr + sizeof (q8_ce_hdr_t));
 1023         rd_e = (q8_poll_rd_e_t *)((uint8_t *)phdr + sizeof(q8_poll_hdr_t));
 1024 
 1025         for (i = 0; i < ce_hdr->opcount; i++, rd_e++) {
 1026                 if (ql_rdwr_indreg32(ha, rd_e->ar_addr, &rd_e->ar_value, 0)) {
 1027                         device_printf(ha->pci_dev,
 1028                                 "%s: [0x%08x 0x%08x] error\n", __func__,
 1029                                 rd_e->ar_addr, rd_e->ar_value);
 1030                         return -1;
 1031                 }
 1032 
 1033                 if (ce_hdr->delay_to)  {
 1034                         if (qla_poll_reg(ha, rd_e->ar_addr, ce_hdr->delay_to,
 1035                                 phdr->tmask, phdr->tvalue)) {
 1036                                 return (-1);
 1037                         } else {
 1038                                 if (ql_rdwr_indreg32(ha, rd_e->dr_addr,
 1039                                         &value, 1)) {
 1040                                         device_printf(ha->pci_dev,
 1041                                                 "%s: [0x%08x] error\n",
 1042                                                 __func__, rd_e->ar_addr);
 1043                                         return -1;
 1044                                 }
 1045 
 1046                                 ha->hw.rst_seq[ha->hw.rst_seq_idx++] = value;
 1047                                 if (ha->hw.rst_seq_idx == Q8_MAX_RESET_SEQ_IDX)
 1048                                         ha->hw.rst_seq_idx = 1;
 1049                         }
 1050                 }
 1051         }
 1052         return 0;
 1053 }
 1054 
 1055 static int
 1056 qla_rdmwr(qla_host_t *ha, uint32_t raddr, uint32_t waddr, q8_rdmwr_hdr_t *hdr)
 1057 {
 1058         uint32_t value;
 1059 
 1060         if (hdr->index_a >= Q8_MAX_RESET_SEQ_IDX) {
 1061                 device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
 1062                         hdr->index_a);
 1063                 return -1;
 1064         }
 1065 
 1066         if (hdr->index_a) {
 1067                 value = ha->hw.rst_seq[hdr->index_a];
 1068         } else {
 1069                 if (ql_rdwr_indreg32(ha, raddr, &value, 1)) {
 1070                         device_printf(ha->pci_dev, "%s: [0x%08x] error\n",
 1071                                                 __func__, raddr);
 1072                         return -1;
 1073                 }
 1074         }
 1075 
 1076         value &= hdr->and_value;
 1077         value <<= hdr->shl;
 1078         value >>= hdr->shr;
 1079         value |= hdr->or_value;
 1080         value ^= hdr->xor_value;
 1081 
 1082         if (ql_rdwr_indreg32(ha, waddr, &value, 0)) {
 1083                 device_printf(ha->pci_dev, "%s: [0x%08x] error\n", __func__,
 1084                         raddr);
 1085                 return -1;
 1086         }
 1087         return 0;
 1088 }
 1089 
 1090 static int
 1091 qla_read_modify_write_list(qla_host_t *ha, q8_ce_hdr_t *ce_hdr)
 1092 {
 1093         int             i;
 1094         q8_rdmwr_hdr_t  *rdmwr_hdr;
 1095         q8_rdmwr_e_t    *rdmwr_e;
 1096 
 1097         rdmwr_hdr = (q8_rdmwr_hdr_t *)((uint8_t *)ce_hdr +
 1098                                                 sizeof (q8_ce_hdr_t));
 1099         rdmwr_e = (q8_rdmwr_e_t *)((uint8_t *)rdmwr_hdr +
 1100                                         sizeof(q8_rdmwr_hdr_t));
 1101 
 1102         for (i = 0; i < ce_hdr->opcount; i++, rdmwr_e++) {
 1103                 if (qla_rdmwr(ha, rdmwr_e->rd_addr, rdmwr_e->wr_addr,
 1104                         rdmwr_hdr)) {
 1105                         return -1;
 1106                 }
 1107                 if (ce_hdr->delay_to) {
 1108                         DELAY(ce_hdr->delay_to);
 1109                 }
 1110         }
 1111         return 0;
 1112 }
 1113 
 1114 static int
 1115 qla_tmplt_execute(qla_host_t *ha, uint8_t *buf, int start_idx, int *end_idx,
 1116         uint32_t nentries)
 1117 {
 1118         int i, ret = 0, proc_end = 0;
 1119         q8_ce_hdr_t     *ce_hdr;
 1120 
 1121         for (i = start_idx; ((i < nentries) && (!proc_end)); i++) {
 1122                 ce_hdr = (q8_ce_hdr_t *)buf;
 1123                 ret = 0;
 1124 
 1125                 switch (ce_hdr->opcode) {
 1126                 case Q8_CE_OPCODE_NOP:
 1127                         break;
 1128 
 1129                 case Q8_CE_OPCODE_WRITE_LIST:
 1130                         ret = qla_wr_list(ha, ce_hdr);
 1131                         //printf("qla_wr_list %d\n", ret);
 1132                         break;
 1133 
 1134                 case Q8_CE_OPCODE_READ_WRITE_LIST:
 1135                         ret = qla_rd_wr_list(ha, ce_hdr);
 1136                         //printf("qla_rd_wr_list %d\n", ret);
 1137                         break;
 1138 
 1139                 case Q8_CE_OPCODE_POLL_LIST:
 1140                         ret = qla_poll_list(ha, ce_hdr);
 1141                         //printf("qla_poll_list %d\n", ret);
 1142                         break;
 1143 
 1144                 case Q8_CE_OPCODE_POLL_WRITE_LIST:
 1145                         ret = qla_poll_write_list(ha, ce_hdr);
 1146                         //printf("qla_poll_write_list %d\n", ret);
 1147                         break;
 1148 
 1149                 case Q8_CE_OPCODE_POLL_RD_LIST:
 1150                         ret = qla_poll_read_list(ha, ce_hdr);
 1151                         //printf("qla_poll_read_list %d\n", ret);
 1152                         break;
 1153 
 1154                 case Q8_CE_OPCODE_READ_MODIFY_WRITE:
 1155                         ret = qla_read_modify_write_list(ha, ce_hdr);
 1156                         //printf("qla_read_modify_write_list %d\n", ret);
 1157                         break;
 1158 
 1159                 case Q8_CE_OPCODE_SEQ_PAUSE:
 1160                         if (ce_hdr->delay_to) {
 1161                                 qla_mdelay(__func__, ce_hdr->delay_to);
 1162                         }
 1163                         break;
 1164 
 1165                 case Q8_CE_OPCODE_SEQ_END:
 1166                         proc_end = 1;
 1167                         break;
 1168 
 1169                 case Q8_CE_OPCODE_TMPLT_END:
 1170                         *end_idx = i;
 1171                         return 0;
 1172                 }
 1173 
 1174                 if (ret)
 1175                         break;
 1176 
 1177                 buf += ce_hdr->size;
 1178         }
 1179         *end_idx = i;
 1180 
 1181         return (ret);
 1182 }
 1183 
 1184 #ifndef QL_LDFLASH_FW
 1185 static int
 1186 qla_load_offchip_mem(qla_host_t *ha, uint64_t addr, uint32_t *data32,
 1187         uint32_t len32)
 1188 {
 1189         q80_offchip_mem_val_t val;
 1190         int             ret = 0;
 1191 
 1192         while (len32) {
 1193                 if (len32 > 4) {
 1194                         val.data_lo = *data32++;
 1195                         val.data_hi = *data32++;
 1196                         val.data_ulo = *data32++;
 1197                         val.data_uhi = *data32++;
 1198                         len32 -= 4;
 1199                         if (ql_rdwr_offchip_mem(ha, addr, &val, 0))
 1200                                 return -1;
 1201 
 1202                         addr += (uint64_t)16;
 1203                 } else {
 1204                         break;
 1205                 }
 1206         }
 1207 
 1208         bzero(&val, sizeof(q80_offchip_mem_val_t));
 1209 
 1210         switch (len32) {
 1211         case 3:
 1212                 val.data_lo = *data32++;
 1213                 val.data_hi = *data32++;
 1214                 val.data_ulo = *data32++;
 1215                  ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
 1216                 break;
 1217 
 1218         case 2:
 1219                 val.data_lo = *data32++;
 1220                 val.data_hi = *data32++;
 1221                  ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
 1222                 break;
 1223 
 1224         case 1:
 1225                 val.data_lo = *data32++;
 1226                 ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
 1227                 break;
 1228 
 1229         default:
 1230                 break;
 1231         }
 1232         return ret;
 1233 }
 1234 
 1235 static int
 1236 qla_load_bootldr(qla_host_t *ha)
 1237 {
 1238         uint64_t        addr;
 1239         uint32_t        *data32;
 1240         uint32_t        len32;
 1241         int             ret;
 1242 
 1243         addr = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
 1244         data32 = (uint32_t *)ql83xx_bootloader;
 1245         len32 = ql83xx_bootloader_len >> 2;
 1246 
 1247         ret = qla_load_offchip_mem(ha, addr, data32, len32);
 1248 
 1249         return (ret);
 1250 }
 1251 
 1252 static int
 1253 qla_load_fwimage(qla_host_t *ha)
 1254 {
 1255         uint64_t        addr;
 1256         uint32_t        *data32;
 1257         uint32_t        len32;
 1258         int             ret;
 1259 
 1260         addr = (uint64_t)(READ_REG32(ha, Q8_FW_IMAGE_ADDR));
 1261         data32 = (uint32_t *)ql83xx_firmware;
 1262         len32 = ql83xx_firmware_len >> 2;
 1263 
 1264         ret = qla_load_offchip_mem(ha, addr, data32, len32);
 1265 
 1266         return (ret);
 1267 }
 1268 #endif /* #ifndef QL_LDFLASH_FW */
 1269 
 1270 static int
 1271 qla_ld_fw_init(qla_host_t *ha)
 1272 {
 1273         uint8_t *buf;
 1274         uint32_t index = 0, end_idx;
 1275         q8_tmplt_hdr_t *hdr;
 1276 
 1277         bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
 1278 
 1279         hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
 1280 
 1281         device_printf(ha->pci_dev, "%s: reset sequence\n", __func__);
 1282         if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
 1283                 (uint32_t)hdr->size)) {
 1284                 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
 1285                         __func__);
 1286                 return -1;
 1287         }
 1288 
 1289         buf = ql83xx_resetseq + hdr->stop_seq_off;
 1290 
 1291         device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
 1292         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
 1293                 device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
 1294                 return -1;
 1295         }
 1296 
 1297         index = end_idx;
 1298 
 1299         buf = ql83xx_resetseq + hdr->init_seq_off;
 1300 
 1301         device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
 1302         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
 1303                 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
 1304                 return -1;
 1305         }
 1306 
 1307 #ifdef QL_LDFLASH_FW
 1308         qla_load_fw_from_flash(ha);
 1309         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
 1310 #else
 1311         if (qla_load_bootldr(ha))
 1312                 return -1;
 1313 
 1314         if (qla_load_fwimage(ha))
 1315                 return -1;
 1316 
 1317         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
 1318 #endif /* #ifdef QL_LDFLASH_FW */
 1319 
 1320         index = end_idx;
 1321         buf = ql83xx_resetseq + hdr->start_seq_off;
 1322 
 1323         device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
 1324         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
 1325                 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
 1326                 return -1;
 1327         }
 1328 
 1329         return 0;
 1330 }
 1331 
 1332 int
 1333 ql_stop_sequence(qla_host_t *ha)
 1334 {
 1335         uint8_t *buf;
 1336         uint32_t index = 0, end_idx;
 1337         q8_tmplt_hdr_t *hdr;
 1338 
 1339         bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
 1340 
 1341         hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
 1342 
 1343         if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
 1344                 (uint32_t)hdr->size)) {
 1345                 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
 1346                 __func__);
 1347                 return (-1);
 1348         }
 1349 
 1350         buf = ql83xx_resetseq + hdr->stop_seq_off;
 1351 
 1352         device_printf(ha->pci_dev, "%s: stop sequence\n", __func__);
 1353         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
 1354                 device_printf(ha->pci_dev, "%s: stop seq failed\n", __func__);
 1355                 return (-1);
 1356         }
 1357 
 1358         return end_idx;
 1359 }
 1360 
 1361 int
 1362 ql_start_sequence(qla_host_t *ha, uint16_t index)
 1363 {
 1364         uint8_t *buf;
 1365         uint32_t end_idx;
 1366         q8_tmplt_hdr_t *hdr;
 1367 
 1368         bzero(ha->hw.rst_seq, sizeof (ha->hw.rst_seq));
 1369 
 1370         hdr = (q8_tmplt_hdr_t *)ql83xx_resetseq;
 1371 
 1372         if (qla_tmplt_16bit_checksum(ha, (uint16_t *)ql83xx_resetseq,
 1373                 (uint32_t)hdr->size)) {
 1374                 device_printf(ha->pci_dev, "%s: reset seq checksum failed\n",
 1375                 __func__);
 1376                 return (-1);
 1377         }
 1378 
 1379         buf = ql83xx_resetseq + hdr->init_seq_off;
 1380 
 1381         device_printf(ha->pci_dev, "%s: init sequence\n", __func__);
 1382         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
 1383                 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
 1384                 return (-1);
 1385         }
 1386 
 1387 #ifdef QL_LDFLASH_FW
 1388         qla_load_fw_from_flash(ha);
 1389         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
 1390 #else
 1391         if (qla_load_bootldr(ha))
 1392                 return -1;
 1393 
 1394         if (qla_load_fwimage(ha))
 1395                 return -1;
 1396 
 1397         WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
 1398 #endif /* #ifdef QL_LDFLASH_FW */
 1399 
 1400         index = end_idx;
 1401         buf = ql83xx_resetseq + hdr->start_seq_off;
 1402 
 1403         device_printf(ha->pci_dev, "%s: start sequence\n", __func__);
 1404         if (qla_tmplt_execute(ha, buf, index , &end_idx, hdr->nentries)) {
 1405                 device_printf(ha->pci_dev, "%s: init seq failed\n", __func__);
 1406                 return -1;
 1407         }
 1408 
 1409         return (0);
 1410 }

Cache object: 4b9a14dbb4124cbc8d62d317ce21995b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.