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/qlxge/qls_hw.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  * Copyright (c) 2013-2014 Qlogic Corporation
    3  * All rights reserved.
    4  *
    5  *  Redistribution and use in source and binary forms, with or without
    6  *  modification, are permitted provided that the following conditions
    7  *  are met:
    8  *
    9  *  1. Redistributions of source code must retain the above copyright
   10  *     notice, this list of conditions and the following disclaimer.
   11  *  2. Redistributions in binary form must reproduce the above copyright
   12  *     notice, this list of conditions and the following disclaimer in the
   13  *     documentation and/or other materials provided with the distribution.
   14  *
   15  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   16  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   19  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   20  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   21  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   22  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   23  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   24  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   25  *  POSSIBILITY OF SUCH DAMAGE.
   26  */
   27 
   28 /*
   29  * File: qls_hw.c
   30  * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656.
   31  * Content: Contains Hardware dependant functions
   32  */
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 
   37 
   38 #include "qls_os.h"
   39 #include "qls_hw.h"
   40 #include "qls_def.h"
   41 #include "qls_inline.h"
   42 #include "qls_ver.h"
   43 #include "qls_glbl.h"
   44 #include "qls_dbg.h"
   45 
   46 /*
   47  * Static Functions
   48  */
   49 static int qls_wait_for_mac_proto_idx_ready(qla_host_t *ha, uint32_t op);
   50 static int qls_config_unicast_mac_addr(qla_host_t *ha, uint32_t add_mac);
   51 static int qls_config_mcast_mac_addr(qla_host_t *ha, uint8_t *mac_addr,
   52                 uint32_t add_mac, uint32_t index);
   53 
   54 static int qls_init_rss(qla_host_t *ha);
   55 static int qls_init_comp_queue(qla_host_t *ha, int cid);
   56 static int qls_init_work_queue(qla_host_t *ha, int wid);
   57 static int qls_init_fw_routing_table(qla_host_t *ha);
   58 static int qls_hw_add_all_mcast(qla_host_t *ha);
   59 static int qls_hw_add_mcast(qla_host_t *ha, uint8_t *mta);
   60 static int qls_hw_del_mcast(qla_host_t *ha, uint8_t *mta);
   61 static int qls_wait_for_flash_ready(qla_host_t *ha);
   62 
   63 static int qls_sem_lock(qla_host_t *ha, uint32_t mask, uint32_t value);
   64 static void qls_sem_unlock(qla_host_t *ha, uint32_t mask);
   65 
   66 static void qls_free_tx_dma(qla_host_t *ha);
   67 static int qls_alloc_tx_dma(qla_host_t *ha);
   68 static void qls_free_rx_dma(qla_host_t *ha);
   69 static int qls_alloc_rx_dma(qla_host_t *ha);
   70 static void qls_free_mpi_dma(qla_host_t *ha);
   71 static int qls_alloc_mpi_dma(qla_host_t *ha);
   72 static void qls_free_rss_dma(qla_host_t *ha);
   73 static int qls_alloc_rss_dma(qla_host_t *ha);
   74 
   75 static int qls_flash_validate(qla_host_t *ha, const char *signature);
   76 
   77 
   78 static int qls_wait_for_proc_addr_ready(qla_host_t *ha);
   79 static int qls_proc_addr_rd_reg(qla_host_t *ha, uint32_t addr_module,
   80                 uint32_t reg, uint32_t *data);
   81 static int qls_proc_addr_wr_reg(qla_host_t *ha, uint32_t addr_module,
   82                 uint32_t reg, uint32_t data);
   83 
   84 static int qls_hw_reset(qla_host_t *ha);
   85 
   86 /*
   87  * MPI Related Functions
   88  */
   89 static int qls_mbx_cmd(qla_host_t *ha, uint32_t *in_mbx, uint32_t i_count,
   90                 uint32_t *out_mbx, uint32_t o_count);
   91 static int qls_mbx_set_mgmt_ctrl(qla_host_t *ha, uint32_t t_ctrl);
   92 static int qls_mbx_get_mgmt_ctrl(qla_host_t *ha, uint32_t *t_status);
   93 static void qls_mbx_get_link_status(qla_host_t *ha);
   94 static void qls_mbx_about_fw(qla_host_t *ha);
   95 
   96 int
   97 qls_get_msix_count(qla_host_t *ha)
   98 {
   99         return (ha->num_rx_rings);
  100 }
  101 
  102 static int
  103 qls_syctl_mpi_dump(SYSCTL_HANDLER_ARGS)
  104 {
  105         int err = 0, ret;
  106         qla_host_t *ha;
  107 
  108         err = sysctl_handle_int(oidp, &ret, 0, req);
  109 
  110         if (err || !req->newptr)
  111                 return (err);
  112 
  113 
  114         if (ret == 1) {
  115                 ha = (qla_host_t *)arg1;
  116                 qls_mpi_core_dump(ha);
  117         }
  118         return (err);
  119 }
  120 
  121 static int
  122 qls_syctl_link_status(SYSCTL_HANDLER_ARGS)
  123 {
  124         int err = 0, ret;
  125         qla_host_t *ha;
  126 
  127         err = sysctl_handle_int(oidp, &ret, 0, req);
  128 
  129         if (err || !req->newptr)
  130                 return (err);
  131 
  132 
  133         if (ret == 1) {
  134                 ha = (qla_host_t *)arg1;
  135                 qls_mbx_get_link_status(ha);
  136                 qls_mbx_about_fw(ha);
  137         }
  138         return (err);
  139 }
  140 
  141 void
  142 qls_hw_add_sysctls(qla_host_t *ha)
  143 {
  144         device_t        dev;
  145 
  146         dev = ha->pci_dev;
  147 
  148         ha->num_rx_rings = MAX_RX_RINGS; ha->num_tx_rings = MAX_TX_RINGS;
  149 
  150         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
  151                 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
  152                 OID_AUTO, "num_rx_rings", CTLFLAG_RD, &ha->num_rx_rings,
  153                 ha->num_rx_rings, "Number of Completion Queues");
  154 
  155         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
  156                 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
  157                 OID_AUTO, "num_tx_rings", CTLFLAG_RD, &ha->num_tx_rings,
  158                 ha->num_tx_rings, "Number of Transmit Rings");
  159 
  160         SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
  161                 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
  162                 OID_AUTO, "mpi_dump", CTLTYPE_INT | CTLFLAG_RW,
  163                 (void *)ha, 0,
  164                 qls_syctl_mpi_dump, "I", "MPI Dump");
  165 
  166         SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
  167                 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
  168                 OID_AUTO, "link_status", CTLTYPE_INT | CTLFLAG_RW,
  169                 (void *)ha, 0,
  170                 qls_syctl_link_status, "I", "Link Status");
  171 }
  172 
  173 /*
  174  * Name: qls_free_dma
  175  * Function: Frees the DMA'able memory allocated in qls_alloc_dma()
  176  */
  177 void
  178 qls_free_dma(qla_host_t *ha)
  179 {
  180         qls_free_rss_dma(ha);
  181         qls_free_mpi_dma(ha);
  182         qls_free_tx_dma(ha);
  183         qls_free_rx_dma(ha);
  184         return;
  185 }
  186 
  187 /*
  188  * Name: qls_alloc_dma
  189  * Function: Allocates DMA'able memory for Tx/Rx Rings, Tx/Rx Contexts.
  190  */
  191 int
  192 qls_alloc_dma(qla_host_t *ha)
  193 {
  194         if (qls_alloc_rx_dma(ha))
  195                 return (-1);
  196 
  197         if (qls_alloc_tx_dma(ha)) {
  198                 qls_free_rx_dma(ha);
  199                 return (-1);
  200         }
  201 
  202         if (qls_alloc_mpi_dma(ha)) {
  203                 qls_free_tx_dma(ha);
  204                 qls_free_rx_dma(ha);
  205                 return (-1);
  206         }
  207 
  208         if (qls_alloc_rss_dma(ha)) {
  209                 qls_free_mpi_dma(ha);
  210                 qls_free_tx_dma(ha);
  211                 qls_free_rx_dma(ha);
  212                 return (-1);
  213         }
  214 
  215         return (0);
  216 }
  217 
  218 
  219 static int
  220 qls_wait_for_mac_proto_idx_ready(qla_host_t *ha, uint32_t op)
  221 {
  222         uint32_t data32;
  223         uint32_t count = 3;
  224 
  225         while (count--) {
  226                 data32 = READ_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX);
  227 
  228                 if (data32 & op)
  229                         return (0);
  230 
  231                 QLA_USEC_DELAY(100);
  232         }
  233         ha->qla_initiate_recovery = 1;
  234         return (-1);
  235 }
  236 
  237 /*
  238  * Name: qls_config_unicast_mac_addr
  239  * Function: binds/unbinds a unicast MAC address to the interface.
  240  */
  241 static int
  242 qls_config_unicast_mac_addr(qla_host_t *ha, uint32_t add_mac)
  243 {
  244         int ret = 0;
  245         uint32_t mac_upper = 0;
  246         uint32_t mac_lower = 0;
  247         uint32_t value = 0, index;
  248 
  249         if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_MAC_SERDES,
  250                 Q81_CTL_SEM_SET_MAC_SERDES)) {
  251                 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
  252                 return(-1);
  253         }
  254 
  255         if (add_mac) {
  256                 mac_upper = (ha->mac_addr[0] << 8) | ha->mac_addr[1];
  257                 mac_lower = (ha->mac_addr[2] << 24) | (ha->mac_addr[3] << 16) |
  258                                 (ha->mac_addr[4] << 8) | ha->mac_addr[5];
  259         }
  260         ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
  261         if (ret)
  262                 goto qls_config_unicast_mac_addr_exit;
  263         
  264         index = 128 * (ha->pci_func & 0x1); /* index */
  265 
  266         value = (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
  267                 Q81_CTL_MAC_PROTO_AI_TYPE_CAM_MAC;
  268 
  269         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
  270         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_lower);
  271 
  272         ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
  273         if (ret)
  274                 goto qls_config_unicast_mac_addr_exit;
  275 
  276         value = (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
  277                 Q81_CTL_MAC_PROTO_AI_TYPE_CAM_MAC | 0x1;
  278 
  279         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
  280         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_upper);
  281 
  282         ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
  283         if (ret)
  284                 goto qls_config_unicast_mac_addr_exit;
  285 
  286         value = (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
  287                 Q81_CTL_MAC_PROTO_AI_TYPE_CAM_MAC | 0x2;
  288 
  289         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
  290 
  291         value = Q81_CAM_MAC_OFF2_ROUTE_NIC |
  292                         ((ha->pci_func & 0x1) << Q81_CAM_MAC_OFF2_FUNC_SHIFT) |
  293                         (0 << Q81_CAM_MAC_OFF2_CQID_SHIFT);
  294 
  295         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, value);
  296 
  297 qls_config_unicast_mac_addr_exit:
  298         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_MAC_SERDES);
  299         return (ret);
  300 }
  301 
  302 /*
  303  * Name: qls_config_mcast_mac_addr
  304  * Function: binds/unbinds a multicast MAC address to the interface.
  305  */
  306 static int
  307 qls_config_mcast_mac_addr(qla_host_t *ha, uint8_t *mac_addr, uint32_t add_mac,
  308         uint32_t index)
  309 {
  310         int ret = 0;
  311         uint32_t mac_upper = 0;
  312         uint32_t mac_lower = 0;
  313         uint32_t value = 0;
  314 
  315         if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_MAC_SERDES,
  316                 Q81_CTL_SEM_SET_MAC_SERDES)) {
  317                 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
  318                 return(-1);
  319         }
  320 
  321         if (add_mac) {
  322                 mac_upper = (mac_addr[0] << 8) | mac_addr[1];
  323                 mac_lower = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
  324                                 (mac_addr[4] << 8) | mac_addr[5];
  325         }
  326         ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
  327         if (ret)
  328                 goto qls_config_mcast_mac_addr_exit;
  329         
  330         value = Q81_CTL_MAC_PROTO_AI_E |
  331                         (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
  332                         Q81_CTL_MAC_PROTO_AI_TYPE_MCAST ;
  333 
  334         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
  335         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_lower);
  336 
  337         ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW);
  338         if (ret)
  339                 goto qls_config_mcast_mac_addr_exit;
  340 
  341         value = Q81_CTL_MAC_PROTO_AI_E |
  342                         (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) |
  343                         Q81_CTL_MAC_PROTO_AI_TYPE_MCAST | 0x1;
  344 
  345         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value);
  346         WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_upper);
  347 
  348 qls_config_mcast_mac_addr_exit:
  349         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_MAC_SERDES);
  350 
  351         return (ret);
  352 }
  353 
  354 /*
  355  * Name: qls_set_mac_rcv_mode
  356  * Function: Enable/Disable AllMulticast and Promiscous Modes.
  357  */
  358 static int
  359 qls_wait_for_route_idx_ready(qla_host_t *ha, uint32_t op)
  360 {
  361         uint32_t data32;
  362         uint32_t count = 3;
  363 
  364         while (count--) {
  365                 data32 = READ_REG32(ha, Q81_CTL_ROUTING_INDEX);
  366 
  367                 if (data32 & op)
  368                         return (0);
  369 
  370                 QLA_USEC_DELAY(100);
  371         }
  372         ha->qla_initiate_recovery = 1;
  373         return (-1);
  374 }
  375 
  376 static int
  377 qls_load_route_idx_reg(qla_host_t *ha, uint32_t index, uint32_t data)
  378 {
  379         int ret = 0;
  380 
  381         ret = qls_wait_for_route_idx_ready(ha, Q81_CTL_RI_MW);
  382 
  383         if (ret) {
  384                 device_printf(ha->pci_dev, "%s: [0x%08x, 0x%08x] failed\n",
  385                         __func__, index, data);
  386                 goto qls_load_route_idx_reg_exit;
  387         }
  388 
  389         
  390         WRITE_REG32(ha, Q81_CTL_ROUTING_INDEX, index);
  391         WRITE_REG32(ha, Q81_CTL_ROUTING_DATA, data);
  392 
  393 qls_load_route_idx_reg_exit:
  394         return (ret);
  395 }
  396 
  397 static int
  398 qls_load_route_idx_reg_locked(qla_host_t *ha, uint32_t index, uint32_t data)
  399 {
  400         int ret = 0;
  401 
  402         if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG,
  403                 Q81_CTL_SEM_SET_RIDX_DATAREG)) {
  404                 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
  405                 return(-1);
  406         }
  407 
  408         ret = qls_load_route_idx_reg(ha, index, data);
  409 
  410         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG);
  411 
  412         return (ret);
  413 }
  414 
  415 static int
  416 qls_clear_routing_table(qla_host_t *ha)
  417 {
  418         int i, ret = 0;
  419 
  420         if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG,
  421                 Q81_CTL_SEM_SET_RIDX_DATAREG)) {
  422                 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
  423                 return(-1);
  424         }
  425 
  426         for (i = 0; i < 16; i++) {
  427                 ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_TYPE_NICQMASK|
  428                         (i << 8) | Q81_CTL_RI_DST_DFLTQ), 0);
  429                 if (ret)
  430                         break;
  431         }
  432 
  433         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG);
  434 
  435         return (ret);
  436 }
  437 
  438 int
  439 qls_set_promisc(qla_host_t *ha)
  440 {
  441         int ret;
  442 
  443         ret = qls_load_route_idx_reg_locked(ha,
  444                         (Q81_CTL_RI_E | Q81_CTL_RI_TYPE_NICQMASK |
  445                         Q81_CTL_RI_IDX_PROMISCUOUS | Q81_CTL_RI_DST_DFLTQ),
  446                         Q81_CTL_RD_VALID_PKT);
  447         return (ret);
  448 }
  449 
  450 void
  451 qls_reset_promisc(qla_host_t *ha)
  452 {
  453         int ret;
  454 
  455         ret = qls_load_route_idx_reg_locked(ha, (Q81_CTL_RI_TYPE_NICQMASK |
  456                         Q81_CTL_RI_IDX_PROMISCUOUS | Q81_CTL_RI_DST_DFLTQ), 0);
  457         return;
  458 }
  459 
  460 int
  461 qls_set_allmulti(qla_host_t *ha)
  462 {
  463         int ret;
  464 
  465         ret = qls_load_route_idx_reg_locked(ha,
  466                         (Q81_CTL_RI_E | Q81_CTL_RI_TYPE_NICQMASK |
  467                         Q81_CTL_RI_IDX_ALLMULTI | Q81_CTL_RI_DST_DFLTQ),
  468                         Q81_CTL_RD_MCAST);
  469         return (ret);
  470 }
  471 
  472 void
  473 qls_reset_allmulti(qla_host_t *ha)
  474 {
  475         int ret;
  476 
  477         ret = qls_load_route_idx_reg_locked(ha, (Q81_CTL_RI_TYPE_NICQMASK |
  478                         Q81_CTL_RI_IDX_ALLMULTI | Q81_CTL_RI_DST_DFLTQ), 0);
  479         return;
  480 }
  481 
  482 
  483 static int
  484 qls_init_fw_routing_table(qla_host_t *ha)
  485 {
  486         int ret = 0;
  487 
  488         ret = qls_clear_routing_table(ha);
  489         if (ret)
  490                 return (-1);
  491 
  492         if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG,
  493                 Q81_CTL_SEM_SET_RIDX_DATAREG)) {
  494                 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
  495                 return(-1);
  496         }
  497 
  498         ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DROP |
  499                         Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_ALL_ERROR),
  500                         Q81_CTL_RD_ERROR_PKT);
  501         if (ret)
  502                 goto qls_init_fw_routing_table_exit;
  503 
  504         ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DFLTQ |
  505                         Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_BCAST),
  506                         Q81_CTL_RD_BCAST);
  507         if (ret)
  508                 goto qls_init_fw_routing_table_exit;
  509 
  510         if (ha->num_rx_rings > 1 ) {
  511                 ret = qls_load_route_idx_reg(ha,
  512                                 (Q81_CTL_RI_E | Q81_CTL_RI_DST_RSS |
  513                                 Q81_CTL_RI_TYPE_NICQMASK |
  514                                 Q81_CTL_RI_IDX_RSS_MATCH),
  515                                 Q81_CTL_RD_RSS_MATCH);
  516                 if (ret)
  517                         goto qls_init_fw_routing_table_exit;
  518         }
  519 
  520         ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DFLTQ |
  521                         Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_MCAST_MATCH),
  522                         Q81_CTL_RD_MCAST_REG_MATCH);
  523         if (ret)
  524                 goto qls_init_fw_routing_table_exit;
  525 
  526         ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DFLTQ |
  527                         Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_CAM_HIT),
  528                         Q81_CTL_RD_CAM_HIT);
  529         if (ret)
  530                 goto qls_init_fw_routing_table_exit;
  531 
  532 qls_init_fw_routing_table_exit:
  533         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG);
  534         return (ret);
  535 }
  536 
  537 static int
  538 qls_tx_tso_chksum(qla_host_t *ha, struct mbuf *mp, q81_tx_tso_t *tx_mac)
  539 {
  540         struct ether_vlan_header *eh;
  541         struct ip *ip;
  542         struct ip6_hdr *ip6;
  543         struct tcphdr *th;
  544         uint32_t ehdrlen, ip_hlen;
  545         int ret = 0;
  546         uint16_t etype;
  547         device_t dev;
  548         uint8_t buf[sizeof(struct ip6_hdr)];
  549 
  550         dev = ha->pci_dev;
  551 
  552         eh = mtod(mp, struct ether_vlan_header *);
  553 
  554         if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
  555                 ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
  556                 etype = ntohs(eh->evl_proto);
  557         } else {
  558                 ehdrlen = ETHER_HDR_LEN;
  559                 etype = ntohs(eh->evl_encap_proto);
  560         }
  561 
  562         switch (etype) {
  563                 case ETHERTYPE_IP:
  564                         ip = (struct ip *)(mp->m_data + ehdrlen);
  565 
  566                         ip_hlen = sizeof (struct ip);
  567 
  568                         if (mp->m_len < (ehdrlen + ip_hlen)) {
  569                                 m_copydata(mp, ehdrlen, sizeof(struct ip), buf);
  570                                 ip = (struct ip *)buf;
  571                         }
  572                         tx_mac->opcode = Q81_IOCB_TX_TSO;
  573                         tx_mac->flags |= Q81_TX_TSO_FLAGS_IPV4 ;
  574 
  575                         tx_mac->phdr_offsets = ehdrlen;
  576 
  577                         tx_mac->phdr_offsets |= ((ehdrlen + ip_hlen) <<
  578                                                         Q81_TX_TSO_PHDR_SHIFT);
  579 
  580                         ip->ip_sum = 0;
  581 
  582                         if (mp->m_pkthdr.csum_flags & CSUM_TSO) {
  583                                 tx_mac->flags |= Q81_TX_TSO_FLAGS_LSO;
  584                                 
  585                                 th = (struct tcphdr *)(ip + 1);
  586 
  587                                 th->th_sum = in_pseudo(ip->ip_src.s_addr,
  588                                                 ip->ip_dst.s_addr,
  589                                                 htons(IPPROTO_TCP));
  590                                 tx_mac->mss = mp->m_pkthdr.tso_segsz;
  591                                 tx_mac->phdr_length = ip_hlen + ehdrlen +
  592                                                         (th->th_off << 2);
  593                                 break;
  594                         }
  595                         tx_mac->vlan_off |= Q81_TX_TSO_VLAN_OFF_IC ;
  596 
  597 
  598                         if (ip->ip_p == IPPROTO_TCP) {
  599                                 tx_mac->flags |= Q81_TX_TSO_FLAGS_TC;
  600                         } else if (ip->ip_p == IPPROTO_UDP) {
  601                                 tx_mac->flags |= Q81_TX_TSO_FLAGS_UC;
  602                         }
  603                 break;
  604 
  605                 case ETHERTYPE_IPV6:
  606                         ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen);
  607 
  608                         ip_hlen = sizeof(struct ip6_hdr);
  609 
  610                         if (mp->m_len < (ehdrlen + ip_hlen)) {
  611                                 m_copydata(mp, ehdrlen, sizeof (struct ip6_hdr),
  612                                         buf);
  613                                 ip6 = (struct ip6_hdr *)buf;
  614                         }
  615 
  616                         tx_mac->opcode = Q81_IOCB_TX_TSO;
  617                         tx_mac->flags |= Q81_TX_TSO_FLAGS_IPV6 ;
  618                         tx_mac->vlan_off |= Q81_TX_TSO_VLAN_OFF_IC ;
  619 
  620                         tx_mac->phdr_offsets = ehdrlen;
  621                         tx_mac->phdr_offsets |= ((ehdrlen + ip_hlen) <<
  622                                                         Q81_TX_TSO_PHDR_SHIFT);
  623 
  624                         if (ip6->ip6_nxt == IPPROTO_TCP) {
  625                                 tx_mac->flags |= Q81_TX_TSO_FLAGS_TC;
  626                         } else if (ip6->ip6_nxt == IPPROTO_UDP) {
  627                                 tx_mac->flags |= Q81_TX_TSO_FLAGS_UC;
  628                         }
  629                 break;
  630 
  631                 default:
  632                         ret = -1;
  633                 break;
  634         }
  635 
  636         return (ret);
  637 }
  638 
  639 #define QLA_TX_MIN_FREE 2
  640 int
  641 qls_hw_tx_done(qla_host_t *ha, uint32_t txr_idx)
  642 {
  643         uint32_t txr_done, txr_next;
  644 
  645         txr_done = ha->tx_ring[txr_idx].txr_done;
  646         txr_next = ha->tx_ring[txr_idx].txr_next;
  647 
  648         if (txr_done == txr_next) {
  649                 ha->tx_ring[txr_idx].txr_free = NUM_TX_DESCRIPTORS;
  650         } else if (txr_done > txr_next) {
  651                 ha->tx_ring[txr_idx].txr_free = txr_done - txr_next;
  652         } else {
  653                 ha->tx_ring[txr_idx].txr_free = NUM_TX_DESCRIPTORS +
  654                         txr_done - txr_next;
  655         }
  656 
  657         if (ha->tx_ring[txr_idx].txr_free <= QLA_TX_MIN_FREE)
  658                 return (-1);
  659 
  660         return (0);
  661 }
  662 
  663 /*
  664  * Name: qls_hw_send
  665  * Function: Transmits a packet. It first checks if the packet is a
  666  *      candidate for Large TCP Segment Offload and then for UDP/TCP checksum
  667  *      offload. If either of these creteria are not met, it is transmitted
  668  *      as a regular ethernet frame.
  669  */
  670 int
  671 qls_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs,
  672         uint32_t txr_next,  struct mbuf *mp, uint32_t txr_idx)
  673 {
  674         q81_tx_mac_t *tx_mac;
  675         q81_txb_desc_t *tx_desc;
  676         uint32_t total_length = 0;
  677         uint32_t i;
  678         device_t dev;
  679         int ret = 0;
  680 
  681         dev = ha->pci_dev;
  682 
  683         total_length = mp->m_pkthdr.len;
  684 
  685         if (total_length > QLA_MAX_TSO_FRAME_SIZE) {
  686                 device_printf(dev, "%s: total length exceeds maxlen(%d)\n",
  687                         __func__, total_length);
  688                 return (-1);
  689         }
  690 
  691         if (ha->tx_ring[txr_idx].txr_free <= (NUM_TX_DESCRIPTORS >> 2)) {
  692                 if (qls_hw_tx_done(ha, txr_idx)) {
  693                         device_printf(dev, "%s: tx_free[%d] = %d\n",
  694                                 __func__, txr_idx,
  695                                 ha->tx_ring[txr_idx].txr_free);
  696                         return (-1);
  697                 }
  698         }
  699 
  700         tx_mac = (q81_tx_mac_t *)&ha->tx_ring[txr_idx].wq_vaddr[txr_next];
  701 
  702         bzero(tx_mac, sizeof(q81_tx_mac_t));
  703         
  704         if ((mp->m_pkthdr.csum_flags &
  705                         (CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO)) != 0) {
  706 
  707                 ret = qls_tx_tso_chksum(ha, mp, (q81_tx_tso_t *)tx_mac);
  708                 if (ret) 
  709                         return (EINVAL);
  710 
  711                 if (mp->m_pkthdr.csum_flags & CSUM_TSO)
  712                         ha->tx_ring[txr_idx].tx_tso_frames++;
  713                 else
  714                         ha->tx_ring[txr_idx].tx_frames++;
  715                         
  716         } else { 
  717                 tx_mac->opcode = Q81_IOCB_TX_MAC;
  718         }
  719 
  720         if (mp->m_flags & M_VLANTAG) {
  721 
  722                 tx_mac->vlan_tci = mp->m_pkthdr.ether_vtag;
  723                 tx_mac->vlan_off |= Q81_TX_MAC_VLAN_OFF_V;
  724 
  725                 ha->tx_ring[txr_idx].tx_vlan_frames++;
  726         }
  727 
  728         tx_mac->frame_length = total_length;
  729 
  730         tx_mac->tid_lo = txr_next;
  731 
  732         if (nsegs <= MAX_TX_MAC_DESC) {
  733 
  734                 QL_DPRINT2((dev, "%s: 1 [%d, %d]\n", __func__, total_length,
  735                         tx_mac->tid_lo));
  736 
  737                 for (i = 0; i < nsegs; i++) {
  738                         tx_mac->txd[i].baddr = segs->ds_addr;
  739                         tx_mac->txd[i].length = segs->ds_len;
  740                         segs++;
  741                 }
  742                 tx_mac->txd[(nsegs - 1)].flags = Q81_RXB_DESC_FLAGS_E;
  743 
  744         } else {
  745                 QL_DPRINT2((dev, "%s: 2 [%d, %d]\n", __func__, total_length,
  746                         tx_mac->tid_lo));
  747 
  748                 tx_mac->txd[0].baddr =
  749                         ha->tx_ring[txr_idx].tx_buf[txr_next].oal_paddr;
  750                 tx_mac->txd[0].length =
  751                         nsegs * (sizeof(q81_txb_desc_t));
  752                 tx_mac->txd[0].flags = Q81_RXB_DESC_FLAGS_C;
  753 
  754                 tx_desc = ha->tx_ring[txr_idx].tx_buf[txr_next].oal_vaddr;
  755 
  756                 for (i = 0; i < nsegs; i++) {
  757                         tx_desc->baddr = segs->ds_addr;
  758                         tx_desc->length = segs->ds_len;
  759 
  760                         if (i == (nsegs -1))
  761                                 tx_desc->flags = Q81_RXB_DESC_FLAGS_E;
  762                         else
  763                                 tx_desc->flags = 0;
  764 
  765                         segs++;
  766                         tx_desc++;
  767                 }
  768         }
  769         txr_next = (txr_next + 1) & (NUM_TX_DESCRIPTORS - 1);
  770         ha->tx_ring[txr_idx].txr_next = txr_next;
  771 
  772         ha->tx_ring[txr_idx].txr_free--;
  773 
  774         Q81_WR_WQ_PROD_IDX(txr_idx, txr_next);
  775 
  776         return (0);
  777 }
  778 
  779 /*
  780  * Name: qls_del_hw_if
  781  * Function: Destroys the hardware specific entities corresponding to an
  782  *      Ethernet Interface
  783  */
  784 void
  785 qls_del_hw_if(qla_host_t *ha)
  786 {
  787         uint32_t value;
  788         int i;
  789         //int  count;
  790 
  791         if (ha->hw_init == 0) {
  792                 qls_hw_reset(ha);
  793                 return;
  794         }
  795 
  796         for (i = 0;  i < ha->num_tx_rings; i++) {
  797                 Q81_SET_WQ_INVALID(i); 
  798         }
  799         for (i = 0;  i < ha->num_rx_rings; i++) {
  800                 Q81_SET_CQ_INVALID(i);
  801         }
  802 
  803         for (i = 0; i < ha->num_rx_rings; i++) {
  804                 Q81_DISABLE_INTR(ha, i); /* MSI-x i */
  805         }
  806 
  807         value = (Q81_CTL_INTRE_IHD << Q81_CTL_INTRE_MASK_SHIFT);
  808         WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value);
  809 
  810         value = (Q81_CTL_INTRE_EI << Q81_CTL_INTRE_MASK_SHIFT);
  811         WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value);
  812         ha->flags.intr_enable = 0;
  813 
  814         qls_hw_reset(ha);
  815 
  816         return;
  817 }
  818 
  819 /*
  820  * Name: qls_init_hw_if
  821  * Function: Creates the hardware specific entities corresponding to an
  822  *      Ethernet Interface - Transmit and Receive Contexts. Sets the MAC Address
  823  *      corresponding to the interface. Enables LRO if allowed.
  824  */
  825 int
  826 qls_init_hw_if(qla_host_t *ha)
  827 {
  828         device_t        dev;
  829         uint32_t        value;
  830         int             ret = 0;
  831         int             i;
  832 
  833 
  834         QL_DPRINT2((ha->pci_dev, "%s:enter\n", __func__));
  835 
  836         dev = ha->pci_dev;
  837 
  838         ret = qls_hw_reset(ha);
  839         if (ret)
  840                 goto qls_init_hw_if_exit;
  841 
  842         ha->vm_pgsize = 4096;
  843 
  844         /* Enable FAE and EFE bits in System Register */
  845         value = Q81_CTL_SYSTEM_ENABLE_FAE | Q81_CTL_SYSTEM_ENABLE_EFE;
  846         value = (value << Q81_CTL_SYSTEM_MASK_SHIFT) | value;
  847 
  848         WRITE_REG32(ha, Q81_CTL_SYSTEM, value);
  849 
  850         /* Set Default Completion Queue_ID in NIC Rcv Configuration Register */
  851         value = (Q81_CTL_NIC_RCVC_DCQ_MASK << Q81_CTL_NIC_RCVC_MASK_SHIFT);
  852         WRITE_REG32(ha, Q81_CTL_NIC_RCV_CONFIG, value);
  853 
  854         /* Function Specific Control Register - Set Page Size and Enable NIC */
  855         value = Q81_CTL_FUNC_SPECIFIC_FE |
  856                 Q81_CTL_FUNC_SPECIFIC_VM_PGSIZE_MASK |
  857                 Q81_CTL_FUNC_SPECIFIC_EPC_O |
  858                 Q81_CTL_FUNC_SPECIFIC_EPC_I |
  859                 Q81_CTL_FUNC_SPECIFIC_EC;
  860         value = (value << Q81_CTL_FUNC_SPECIFIC_MASK_SHIFT) | 
  861                         Q81_CTL_FUNC_SPECIFIC_FE |
  862                         Q81_CTL_FUNC_SPECIFIC_VM_PGSIZE_4K |
  863                         Q81_CTL_FUNC_SPECIFIC_EPC_O |
  864                         Q81_CTL_FUNC_SPECIFIC_EPC_I |
  865                         Q81_CTL_FUNC_SPECIFIC_EC;
  866 
  867         WRITE_REG32(ha, Q81_CTL_FUNC_SPECIFIC, value);
  868 
  869         /* Interrupt Mask Register */
  870         value = Q81_CTL_INTRM_PI;
  871         value = (value << Q81_CTL_INTRM_MASK_SHIFT) | value;
  872         
  873         WRITE_REG32(ha, Q81_CTL_INTR_MASK, value);
  874 
  875         /* Initialiatize Completion Queue */
  876         for (i = 0; i < ha->num_rx_rings; i++) {
  877                 ret = qls_init_comp_queue(ha, i);
  878                 if (ret)
  879                         goto qls_init_hw_if_exit;
  880         }
  881 
  882         if (ha->num_rx_rings > 1 ) {
  883                 ret = qls_init_rss(ha);
  884                 if (ret)
  885                         goto qls_init_hw_if_exit;
  886         }
  887 
  888         /* Initialize Work Queue */
  889 
  890         for (i = 0; i < ha->num_tx_rings; i++) {
  891                 ret = qls_init_work_queue(ha, i);
  892                 if (ret)
  893                         goto qls_init_hw_if_exit;
  894         }
  895 
  896         if (ret)
  897                 goto qls_init_hw_if_exit;
  898 
  899         /* Set up CAM RAM with MAC Address */
  900         ret = qls_config_unicast_mac_addr(ha, 1);
  901         if (ret)
  902                 goto qls_init_hw_if_exit;
  903 
  904         ret = qls_hw_add_all_mcast(ha);
  905         if (ret)
  906                 goto qls_init_hw_if_exit;
  907 
  908         /* Initialize Firmware Routing Table */
  909         ret = qls_init_fw_routing_table(ha);
  910         if (ret)
  911                 goto qls_init_hw_if_exit;
  912 
  913         /* Get Chip Revision ID */
  914         ha->rev_id = READ_REG32(ha, Q81_CTL_REV_ID);
  915 
  916         /* Enable Global Interrupt */
  917         value = Q81_CTL_INTRE_EI;
  918         value = (value << Q81_CTL_INTRE_MASK_SHIFT) | value;
  919 
  920         WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value);
  921 
  922         /* Enable Interrupt Handshake Disable */
  923         value = Q81_CTL_INTRE_IHD;
  924         value = (value << Q81_CTL_INTRE_MASK_SHIFT) | value;
  925 
  926         WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value);
  927 
  928         /* Enable Completion Interrupt */
  929 
  930         ha->flags.intr_enable = 1;
  931 
  932         for (i = 0; i < ha->num_rx_rings; i++) {
  933                 Q81_ENABLE_INTR(ha, i); /* MSI-x i */
  934         }
  935 
  936         ha->hw_init = 1;
  937 
  938         qls_mbx_get_link_status(ha);
  939 
  940         QL_DPRINT2((ha->pci_dev, "%s:rxr [0x%08x]\n", __func__,
  941                 ha->rx_ring[0].cq_db_offset));
  942         QL_DPRINT2((ha->pci_dev, "%s:txr [0x%08x]\n", __func__,
  943                 ha->tx_ring[0].wq_db_offset));
  944 
  945         for (i = 0; i < ha->num_rx_rings; i++) {
  946 
  947                 Q81_WR_CQ_CONS_IDX(i, 0);
  948                 Q81_WR_LBQ_PROD_IDX(i, ha->rx_ring[i].lbq_in);
  949                 Q81_WR_SBQ_PROD_IDX(i, ha->rx_ring[i].sbq_in);
  950 
  951                 QL_DPRINT2((dev, "%s: [wq_idx, cq_idx, lbq_idx, sbq_idx]"
  952                         "[0x%08x, 0x%08x, 0x%08x, 0x%08x]\n", __func__,
  953                         Q81_RD_WQ_IDX(i), Q81_RD_CQ_IDX(i), Q81_RD_LBQ_IDX(i),
  954                         Q81_RD_SBQ_IDX(i)));
  955         }
  956 
  957         for (i = 0; i < ha->num_rx_rings; i++) {
  958                 Q81_SET_CQ_VALID(i);
  959         }
  960 
  961 qls_init_hw_if_exit:
  962         QL_DPRINT2((ha->pci_dev, "%s:exit\n", __func__));
  963         return (ret);
  964 }
  965 
  966 static int
  967 qls_wait_for_config_reg_bits(qla_host_t *ha, uint32_t bits, uint32_t value)
  968 {
  969         uint32_t data32;
  970         uint32_t count = 3;
  971 
  972         while (count--) {
  973 
  974                 data32 = READ_REG32(ha, Q81_CTL_CONFIG);
  975 
  976                 if ((data32 & bits) == value)
  977                         return (0);
  978                 
  979                 QLA_USEC_DELAY(100);
  980         }
  981         ha->qla_initiate_recovery = 1;
  982         device_printf(ha->pci_dev, "%s: failed\n", __func__);
  983         return (-1);
  984 }
  985 
  986 static uint8_t q81_hash_key[] = {
  987                         0xda, 0x56, 0x5a, 0x6d,
  988                         0xc2, 0x0e, 0x5b, 0x25,
  989                         0x3d, 0x25, 0x67, 0x41,
  990                         0xb0, 0x8f, 0xa3, 0x43,
  991                         0xcb, 0x2b, 0xca, 0xd0,
  992                         0xb4, 0x30, 0x7b, 0xae,
  993                         0xa3, 0x2d, 0xcb, 0x77,
  994                         0x0c, 0xf2, 0x30, 0x80,
  995                         0x3b, 0xb7, 0x42, 0x6a,
  996                         0xfa, 0x01, 0xac, 0xbe };
  997 
  998 static int
  999 qls_init_rss(qla_host_t *ha)
 1000 {
 1001         q81_rss_icb_t   *rss_icb;
 1002         int             ret = 0;
 1003         int             i;
 1004         uint32_t        value;
 1005 
 1006         rss_icb = ha->rss_dma.dma_b;
 1007 
 1008         bzero(rss_icb, sizeof (q81_rss_icb_t));
 1009 
 1010         rss_icb->flags_base_cq_num = Q81_RSS_ICB_FLAGS_L4K |
 1011                                 Q81_RSS_ICB_FLAGS_L6K | Q81_RSS_ICB_FLAGS_LI |
 1012                                 Q81_RSS_ICB_FLAGS_LB | Q81_RSS_ICB_FLAGS_LM |
 1013                                 Q81_RSS_ICB_FLAGS_RT4 | Q81_RSS_ICB_FLAGS_RT6; 
 1014 
 1015         rss_icb->mask = 0x3FF;
 1016 
 1017         for (i = 0; i < Q81_RSS_ICB_NUM_INDTBL_ENTRIES; i++) {
 1018                 rss_icb->cq_id[i] = (i & (ha->num_rx_rings - 1));
 1019         }
 1020 
 1021         memcpy(rss_icb->ipv6_rss_hash_key, q81_hash_key, 40);
 1022         memcpy(rss_icb->ipv4_rss_hash_key, q81_hash_key, 16);
 1023 
 1024         ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LR, 0);
 1025 
 1026         if (ret)
 1027                 goto qls_init_rss_exit;
 1028 
 1029         ret = qls_sem_lock(ha, Q81_CTL_SEM_MASK_ICB, Q81_CTL_SEM_SET_ICB);
 1030 
 1031         if (ret) {
 1032                 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
 1033                 goto qls_init_rss_exit;
 1034         }
 1035 
 1036         value = (uint32_t)ha->rss_dma.dma_addr;
 1037         WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_LO, value);
 1038 
 1039         value = (uint32_t)(ha->rss_dma.dma_addr >> 32);
 1040         WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_HI, value);
 1041 
 1042         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_ICB);
 1043 
 1044         value = (Q81_CTL_CONFIG_LR << Q81_CTL_CONFIG_MASK_SHIFT) |
 1045                         Q81_CTL_CONFIG_LR;
 1046 
 1047         WRITE_REG32(ha, Q81_CTL_CONFIG, value);
 1048 
 1049         ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LR, 0);
 1050 
 1051 qls_init_rss_exit:
 1052         return (ret);
 1053 }
 1054 
 1055 static int
 1056 qls_init_comp_queue(qla_host_t *ha, int cid)
 1057 {
 1058         q81_cq_icb_t    *cq_icb;
 1059         qla_rx_ring_t   *rxr;
 1060         int             ret = 0;
 1061         uint32_t        value;
 1062 
 1063         rxr = &ha->rx_ring[cid];
 1064 
 1065         rxr->cq_db_offset = ha->vm_pgsize * (128 + cid);
 1066 
 1067         cq_icb = rxr->cq_icb_vaddr;
 1068 
 1069         bzero(cq_icb, sizeof (q81_cq_icb_t));
 1070 
 1071         cq_icb->msix_vector = cid;
 1072         cq_icb->flags = Q81_CQ_ICB_FLAGS_LC |
 1073                         Q81_CQ_ICB_FLAGS_LI |
 1074                         Q81_CQ_ICB_FLAGS_LL |
 1075                         Q81_CQ_ICB_FLAGS_LS |
 1076                         Q81_CQ_ICB_FLAGS_LV;
 1077         
 1078         cq_icb->length_v = NUM_CQ_ENTRIES;
 1079 
 1080         cq_icb->cq_baddr_lo = (rxr->cq_base_paddr & 0xFFFFFFFF);
 1081         cq_icb->cq_baddr_hi = (rxr->cq_base_paddr >> 32) & 0xFFFFFFFF;
 1082 
 1083         cq_icb->cqi_addr_lo = (rxr->cqi_paddr & 0xFFFFFFFF);
 1084         cq_icb->cqi_addr_hi = (rxr->cqi_paddr >> 32) & 0xFFFFFFFF;
 1085 
 1086         cq_icb->pkt_idelay = 10;
 1087         cq_icb->idelay = 100;
 1088 
 1089         cq_icb->lbq_baddr_lo = (rxr->lbq_addr_tbl_paddr & 0xFFFFFFFF);
 1090         cq_icb->lbq_baddr_hi = (rxr->lbq_addr_tbl_paddr >> 32) & 0xFFFFFFFF;
 1091 
 1092         cq_icb->lbq_bsize = QLA_LGB_SIZE;
 1093         cq_icb->lbq_length = QLA_NUM_LGB_ENTRIES;
 1094 
 1095         cq_icb->sbq_baddr_lo = (rxr->sbq_addr_tbl_paddr & 0xFFFFFFFF);
 1096         cq_icb->sbq_baddr_hi = (rxr->sbq_addr_tbl_paddr >> 32) & 0xFFFFFFFF;
 1097 
 1098         cq_icb->sbq_bsize = (uint16_t)ha->msize;
 1099         cq_icb->sbq_length = QLA_NUM_SMB_ENTRIES;
 1100 
 1101         QL_DUMP_CQ(ha);
 1102 
 1103         ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LCQ, 0);
 1104 
 1105         if (ret)
 1106                 goto qls_init_comp_queue_exit;
 1107 
 1108         ret = qls_sem_lock(ha, Q81_CTL_SEM_MASK_ICB, Q81_CTL_SEM_SET_ICB);
 1109 
 1110         if (ret) {
 1111                 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
 1112                 goto qls_init_comp_queue_exit;
 1113         }
 1114 
 1115         value = (uint32_t)rxr->cq_icb_paddr;
 1116         WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_LO, value);
 1117 
 1118         value = (uint32_t)(rxr->cq_icb_paddr >> 32);
 1119         WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_HI, value);
 1120 
 1121         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_ICB);
 1122 
 1123         value = Q81_CTL_CONFIG_LCQ | Q81_CTL_CONFIG_Q_NUM_MASK;
 1124         value = (value << Q81_CTL_CONFIG_MASK_SHIFT) | Q81_CTL_CONFIG_LCQ;
 1125         value |= (cid << Q81_CTL_CONFIG_Q_NUM_SHIFT);
 1126         WRITE_REG32(ha, Q81_CTL_CONFIG, value);
 1127 
 1128         ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LCQ, 0);
 1129 
 1130         rxr->cq_next = 0;
 1131         rxr->lbq_next = rxr->lbq_free = 0;
 1132         rxr->sbq_next = rxr->sbq_free = 0;
 1133         rxr->rx_free = rxr->rx_next = 0;
 1134         rxr->lbq_in = (QLA_NUM_LGB_ENTRIES - 1) & ~0xF;
 1135         rxr->sbq_in = (QLA_NUM_SMB_ENTRIES - 1) & ~0xF;
 1136 
 1137 qls_init_comp_queue_exit:
 1138         return (ret);
 1139 }
 1140 
 1141 static int
 1142 qls_init_work_queue(qla_host_t *ha, int wid)
 1143 {
 1144         q81_wq_icb_t    *wq_icb;
 1145         qla_tx_ring_t   *txr;
 1146         int             ret = 0;
 1147         uint32_t        value;
 1148 
 1149         txr = &ha->tx_ring[wid];
 1150 
 1151         txr->wq_db_addr = (struct resource *)((uint8_t *)ha->pci_reg1
 1152                                                 + (ha->vm_pgsize * wid));
 1153 
 1154         txr->wq_db_offset = (ha->vm_pgsize * wid);
 1155 
 1156         wq_icb = txr->wq_icb_vaddr;
 1157         bzero(wq_icb, sizeof (q81_wq_icb_t));
 1158 
 1159         wq_icb->length_v = NUM_TX_DESCRIPTORS  |
 1160                                 Q81_WQ_ICB_VALID;
 1161 
 1162         wq_icb->flags = Q81_WQ_ICB_FLAGS_LO | Q81_WQ_ICB_FLAGS_LI |
 1163                         Q81_WQ_ICB_FLAGS_LB | Q81_WQ_ICB_FLAGS_LC;
 1164 
 1165         wq_icb->wqcqid_rss = wid;
 1166 
 1167         wq_icb->baddr_lo = txr->wq_paddr & 0xFFFFFFFF;
 1168         wq_icb->baddr_hi = (txr->wq_paddr >> 32)& 0xFFFFFFFF;
 1169 
 1170         wq_icb->ci_addr_lo = txr->txr_cons_paddr & 0xFFFFFFFF;
 1171         wq_icb->ci_addr_hi = (txr->txr_cons_paddr >> 32)& 0xFFFFFFFF;
 1172 
 1173         ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LRQ, 0);
 1174 
 1175         if (ret)
 1176                 goto qls_init_wq_exit;
 1177 
 1178         ret = qls_sem_lock(ha, Q81_CTL_SEM_MASK_ICB, Q81_CTL_SEM_SET_ICB);
 1179 
 1180         if (ret) {
 1181                 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
 1182                 goto qls_init_wq_exit;
 1183         }
 1184 
 1185         value = (uint32_t)txr->wq_icb_paddr;
 1186         WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_LO, value);
 1187 
 1188         value = (uint32_t)(txr->wq_icb_paddr >> 32);
 1189         WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_HI, value);
 1190 
 1191         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_ICB);
 1192 
 1193         value = Q81_CTL_CONFIG_LRQ | Q81_CTL_CONFIG_Q_NUM_MASK;
 1194         value = (value << Q81_CTL_CONFIG_MASK_SHIFT) | Q81_CTL_CONFIG_LRQ;
 1195         value |= (wid << Q81_CTL_CONFIG_Q_NUM_SHIFT);
 1196         WRITE_REG32(ha, Q81_CTL_CONFIG, value);
 1197 
 1198         ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LRQ, 0);
 1199 
 1200         txr->txr_free = NUM_TX_DESCRIPTORS;
 1201         txr->txr_next = 0;
 1202         txr->txr_done = 0;
 1203 
 1204 qls_init_wq_exit:
 1205         return (ret);
 1206 }
 1207 
 1208 static int
 1209 qls_hw_add_all_mcast(qla_host_t *ha)
 1210 {
 1211         int i, nmcast;
 1212 
 1213         nmcast = ha->nmcast;
 1214 
 1215         for (i = 0 ; ((i < Q8_MAX_NUM_MULTICAST_ADDRS) && nmcast); i++) {
 1216                 if ((ha->mcast[i].addr[0] != 0) || 
 1217                         (ha->mcast[i].addr[1] != 0) ||
 1218                         (ha->mcast[i].addr[2] != 0) ||
 1219                         (ha->mcast[i].addr[3] != 0) ||
 1220                         (ha->mcast[i].addr[4] != 0) ||
 1221                         (ha->mcast[i].addr[5] != 0)) {
 1222 
 1223                         if (qls_config_mcast_mac_addr(ha, ha->mcast[i].addr,
 1224                                 1, i)) {
 1225                                 device_printf(ha->pci_dev, "%s: failed\n",
 1226                                         __func__);
 1227                                 return (-1);
 1228                         }
 1229 
 1230                         nmcast--;
 1231                 }
 1232         }
 1233         return 0;
 1234 }
 1235 
 1236 static int
 1237 qls_hw_add_mcast(qla_host_t *ha, uint8_t *mta)
 1238 {
 1239         int i;
 1240 
 1241         for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) {
 1242 
 1243                 if (QL_MAC_CMP(ha->mcast[i].addr, mta) == 0)
 1244                         return 0; /* its been already added */
 1245         }
 1246 
 1247         for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) {
 1248 
 1249                 if ((ha->mcast[i].addr[0] == 0) && 
 1250                         (ha->mcast[i].addr[1] == 0) &&
 1251                         (ha->mcast[i].addr[2] == 0) &&
 1252                         (ha->mcast[i].addr[3] == 0) &&
 1253                         (ha->mcast[i].addr[4] == 0) &&
 1254                         (ha->mcast[i].addr[5] == 0)) {
 1255 
 1256                         if (qls_config_mcast_mac_addr(ha, mta, 1, i))
 1257                                 return (-1);
 1258 
 1259                         bcopy(mta, ha->mcast[i].addr, Q8_MAC_ADDR_LEN);
 1260                         ha->nmcast++;   
 1261 
 1262                         return 0;
 1263                 }
 1264         }
 1265         return 0;
 1266 }
 1267 
 1268 static int
 1269 qls_hw_del_mcast(qla_host_t *ha, uint8_t *mta)
 1270 {
 1271         int i;
 1272 
 1273         for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) {
 1274                 if (QL_MAC_CMP(ha->mcast[i].addr, mta) == 0) {
 1275 
 1276                         if (qls_config_mcast_mac_addr(ha, mta, 0, i))
 1277                                 return (-1);
 1278 
 1279                         ha->mcast[i].addr[0] = 0;
 1280                         ha->mcast[i].addr[1] = 0;
 1281                         ha->mcast[i].addr[2] = 0;
 1282                         ha->mcast[i].addr[3] = 0;
 1283                         ha->mcast[i].addr[4] = 0;
 1284                         ha->mcast[i].addr[5] = 0;
 1285 
 1286                         ha->nmcast--;   
 1287 
 1288                         return 0;
 1289                 }
 1290         }
 1291         return 0;
 1292 }
 1293 
 1294 /*
 1295  * Name: qls_hw_set_multi
 1296  * Function: Sets the Multicast Addresses provided the host O.S into the
 1297  *      hardware (for the given interface)
 1298  */
 1299 void
 1300 qls_hw_set_multi(qla_host_t *ha, uint8_t *mta, uint32_t mcnt,
 1301         uint32_t add_mac)
 1302 {
 1303         int i;
 1304 
 1305         for (i = 0; i < mcnt; i++) {
 1306                 if (add_mac) {
 1307                         if (qls_hw_add_mcast(ha, mta))
 1308                                 break;
 1309                 } else {
 1310                         if (qls_hw_del_mcast(ha, mta))
 1311                                 break;
 1312                 }
 1313                         
 1314                 mta += Q8_MAC_ADDR_LEN;
 1315         }
 1316         return;
 1317 }
 1318 
 1319 void
 1320 qls_update_link_state(qla_host_t *ha)
 1321 {
 1322         uint32_t link_state;
 1323         uint32_t prev_link_state;
 1324 
 1325         if (!(ha->ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 1326                 ha->link_up = 0;
 1327                 return;
 1328         }
 1329         link_state = READ_REG32(ha, Q81_CTL_STATUS);
 1330 
 1331         prev_link_state =  ha->link_up;
 1332 
 1333         if ((ha->pci_func & 0x1) == 0)
 1334                 ha->link_up = ((link_state & Q81_CTL_STATUS_PL0)? 1 : 0);
 1335         else
 1336                 ha->link_up = ((link_state & Q81_CTL_STATUS_PL1)? 1 : 0);
 1337 
 1338         if (prev_link_state !=  ha->link_up) {
 1339 
 1340 
 1341                 if (ha->link_up) {
 1342                         if_link_state_change(ha->ifp, LINK_STATE_UP);
 1343                 } else {
 1344                         if_link_state_change(ha->ifp, LINK_STATE_DOWN);
 1345                 }
 1346         }
 1347         return;
 1348 }
 1349 
 1350 static void
 1351 qls_free_tx_ring_dma(qla_host_t *ha, int r_idx)
 1352 {
 1353         if (ha->tx_ring[r_idx].flags.wq_dma) {
 1354                 qls_free_dmabuf(ha, &ha->tx_ring[r_idx].wq_dma);
 1355                 ha->tx_ring[r_idx].flags.wq_dma = 0;
 1356         }
 1357 
 1358         if (ha->tx_ring[r_idx].flags.privb_dma) {
 1359                 qls_free_dmabuf(ha, &ha->tx_ring[r_idx].privb_dma);
 1360                 ha->tx_ring[r_idx].flags.privb_dma = 0;
 1361         }
 1362         return;
 1363 }
 1364 
 1365 static void
 1366 qls_free_tx_dma(qla_host_t *ha)
 1367 {
 1368         int i, j;
 1369         qla_tx_buf_t *txb;
 1370 
 1371         for (i = 0; i < ha->num_tx_rings; i++) {
 1372 
 1373                 qls_free_tx_ring_dma(ha, i);
 1374 
 1375                 for (j = 0; j < NUM_TX_DESCRIPTORS; j++) {
 1376 
 1377                         txb = &ha->tx_ring[i].tx_buf[j];
 1378 
 1379                         if (txb->map) {
 1380                                 bus_dmamap_destroy(ha->tx_tag, txb->map);
 1381                         }
 1382                 }
 1383         }
 1384 
 1385         if (ha->tx_tag != NULL) {
 1386                 bus_dma_tag_destroy(ha->tx_tag);
 1387                 ha->tx_tag = NULL;
 1388         }
 1389 
 1390         return;
 1391 }
 1392 
 1393 static int
 1394 qls_alloc_tx_ring_dma(qla_host_t *ha, int ridx)
 1395 {
 1396         int             ret = 0, i;
 1397         uint8_t         *v_addr;
 1398         bus_addr_t      p_addr;
 1399         qla_tx_buf_t    *txb;
 1400         device_t        dev = ha->pci_dev;
 1401 
 1402         ha->tx_ring[ridx].wq_dma.alignment = 8;
 1403         ha->tx_ring[ridx].wq_dma.size =
 1404                 NUM_TX_DESCRIPTORS * (sizeof (q81_tx_cmd_t));
 1405 
 1406         ret = qls_alloc_dmabuf(ha, &ha->tx_ring[ridx].wq_dma);
 1407 
 1408         if (ret) {
 1409                 device_printf(dev, "%s: [%d] txr failed\n", __func__, ridx);
 1410                 goto qls_alloc_tx_ring_dma_exit;
 1411         }
 1412         ha->tx_ring[ridx].flags.wq_dma = 1;
 1413 
 1414         ha->tx_ring[ridx].privb_dma.alignment = 8;
 1415         ha->tx_ring[ridx].privb_dma.size = QLA_TX_PRIVATE_BSIZE;
 1416 
 1417         ret = qls_alloc_dmabuf(ha, &ha->tx_ring[ridx].privb_dma);
 1418 
 1419         if (ret) {
 1420                 device_printf(dev, "%s: [%d] oalb failed\n", __func__, ridx);
 1421                 goto qls_alloc_tx_ring_dma_exit;
 1422         }
 1423 
 1424         ha->tx_ring[ridx].flags.privb_dma = 1;
 1425 
 1426         ha->tx_ring[ridx].wq_vaddr = ha->tx_ring[ridx].wq_dma.dma_b;
 1427         ha->tx_ring[ridx].wq_paddr = ha->tx_ring[ridx].wq_dma.dma_addr;
 1428 
 1429         v_addr = ha->tx_ring[ridx].privb_dma.dma_b;
 1430         p_addr = ha->tx_ring[ridx].privb_dma.dma_addr;
 1431 
 1432         ha->tx_ring[ridx].wq_icb_vaddr = v_addr;
 1433         ha->tx_ring[ridx].wq_icb_paddr = p_addr;
 1434 
 1435         ha->tx_ring[ridx].txr_cons_vaddr =
 1436                 (uint32_t *)(v_addr + (PAGE_SIZE >> 1));
 1437         ha->tx_ring[ridx].txr_cons_paddr = p_addr + (PAGE_SIZE >> 1);
 1438 
 1439         v_addr = v_addr + (PAGE_SIZE >> 1);
 1440         p_addr = p_addr + (PAGE_SIZE >> 1);
 1441 
 1442         txb = ha->tx_ring[ridx].tx_buf;
 1443 
 1444         for (i = 0; i < NUM_TX_DESCRIPTORS; i++) {
 1445 
 1446                 txb[i].oal_vaddr = v_addr;
 1447                 txb[i].oal_paddr = p_addr;
 1448 
 1449                 v_addr = v_addr + QLA_OAL_BLK_SIZE;
 1450                 p_addr = p_addr + QLA_OAL_BLK_SIZE;
 1451         }
 1452 
 1453 qls_alloc_tx_ring_dma_exit:
 1454         return (ret);
 1455 }
 1456 
 1457 static int
 1458 qls_alloc_tx_dma(qla_host_t *ha)
 1459 {
 1460         int     i, j;
 1461         int     ret = 0;
 1462         qla_tx_buf_t *txb;
 1463 
 1464         if (bus_dma_tag_create(NULL,    /* parent */
 1465                 1, 0,    /* alignment, bounds */
 1466                 BUS_SPACE_MAXADDR,       /* lowaddr */
 1467                 BUS_SPACE_MAXADDR,       /* highaddr */
 1468                 NULL, NULL,      /* filter, filterarg */
 1469                 QLA_MAX_TSO_FRAME_SIZE,     /* maxsize */
 1470                 QLA_MAX_SEGMENTS,        /* nsegments */
 1471                 PAGE_SIZE,        /* maxsegsize */
 1472                 BUS_DMA_ALLOCNOW,        /* flags */
 1473                 NULL,    /* lockfunc */
 1474                 NULL,    /* lockfuncarg */
 1475                 &ha->tx_tag)) {
 1476                 device_printf(ha->pci_dev, "%s: tx_tag alloc failed\n",
 1477                         __func__);
 1478                 return (ENOMEM);
 1479         }
 1480 
 1481         for (i = 0; i < ha->num_tx_rings; i++) {
 1482 
 1483                 ret = qls_alloc_tx_ring_dma(ha, i);
 1484 
 1485                 if (ret) {
 1486                         qls_free_tx_dma(ha);
 1487                         break;
 1488                 }
 1489 
 1490                 for (j = 0; j < NUM_TX_DESCRIPTORS; j++) {
 1491 
 1492                         txb = &ha->tx_ring[i].tx_buf[j];
 1493 
 1494                         ret = bus_dmamap_create(ha->tx_tag,
 1495                                 BUS_DMA_NOWAIT, &txb->map);
 1496                         if (ret) {
 1497                                 ha->err_tx_dmamap_create++;
 1498                                 device_printf(ha->pci_dev,
 1499                                 "%s: bus_dmamap_create failed[%d, %d, %d]\n",
 1500                                 __func__, ret, i, j);
 1501 
 1502                                 qls_free_tx_dma(ha);
 1503 
 1504                                 return (ret);
 1505                         }
 1506                 }
 1507         }
 1508 
 1509         return (ret);
 1510 }
 1511 
 1512 static void
 1513 qls_free_rss_dma(qla_host_t *ha)
 1514 {
 1515         qls_free_dmabuf(ha, &ha->rss_dma);
 1516         ha->flags.rss_dma = 0;
 1517 }
 1518 
 1519 static int
 1520 qls_alloc_rss_dma(qla_host_t *ha)
 1521 {
 1522         int ret = 0;
 1523 
 1524         ha->rss_dma.alignment = 4;
 1525         ha->rss_dma.size = PAGE_SIZE;
 1526 
 1527         ret = qls_alloc_dmabuf(ha, &ha->rss_dma);
 1528 
 1529         if (ret)
 1530                 device_printf(ha->pci_dev, "%s: failed\n", __func__);
 1531         else
 1532                 ha->flags.rss_dma = 1;
 1533 
 1534         return (ret);
 1535 }
 1536 
 1537 static void
 1538 qls_free_mpi_dma(qla_host_t *ha)
 1539 {
 1540         qls_free_dmabuf(ha, &ha->mpi_dma);
 1541         ha->flags.mpi_dma = 0;
 1542 }
 1543 
 1544 static int
 1545 qls_alloc_mpi_dma(qla_host_t *ha)
 1546 {
 1547         int ret = 0;
 1548 
 1549         ha->mpi_dma.alignment = 4;
 1550         ha->mpi_dma.size = (0x4000 * 4);
 1551 
 1552         ret = qls_alloc_dmabuf(ha, &ha->mpi_dma);
 1553         if (ret)
 1554                 device_printf(ha->pci_dev, "%s: failed\n", __func__);
 1555         else
 1556                 ha->flags.mpi_dma = 1;
 1557 
 1558         return (ret);
 1559 }
 1560 
 1561 static void
 1562 qls_free_rx_ring_dma(qla_host_t *ha, int ridx)
 1563 {
 1564         if (ha->rx_ring[ridx].flags.cq_dma) {
 1565                 qls_free_dmabuf(ha, &ha->rx_ring[ridx].cq_dma);
 1566                 ha->rx_ring[ridx].flags.cq_dma = 0;
 1567         }
 1568 
 1569         if (ha->rx_ring[ridx].flags.lbq_dma) {
 1570                 qls_free_dmabuf(ha, &ha->rx_ring[ridx].lbq_dma);
 1571                 ha->rx_ring[ridx].flags.lbq_dma = 0;
 1572         }
 1573 
 1574         if (ha->rx_ring[ridx].flags.sbq_dma) {
 1575                 qls_free_dmabuf(ha, &ha->rx_ring[ridx].sbq_dma);
 1576                 ha->rx_ring[ridx].flags.sbq_dma = 0;
 1577         }
 1578 
 1579         if (ha->rx_ring[ridx].flags.lb_dma) {
 1580                 qls_free_dmabuf(ha, &ha->rx_ring[ridx].lb_dma);
 1581                 ha->rx_ring[ridx].flags.lb_dma = 0;
 1582         }
 1583         return;
 1584 }
 1585 
 1586 static void
 1587 qls_free_rx_dma(qla_host_t *ha)
 1588 {
 1589         int i;
 1590 
 1591         for (i = 0; i < ha->num_rx_rings; i++) {
 1592                 qls_free_rx_ring_dma(ha, i);
 1593         }
 1594 
 1595         if (ha->rx_tag != NULL) {
 1596                 bus_dma_tag_destroy(ha->rx_tag);
 1597                 ha->rx_tag = NULL;
 1598         }
 1599 
 1600         return;
 1601 }
 1602 
 1603 static int
 1604 qls_alloc_rx_ring_dma(qla_host_t *ha, int ridx)
 1605 {
 1606         int                             i, ret = 0;
 1607         uint8_t                         *v_addr;
 1608         bus_addr_t                      p_addr;
 1609         volatile q81_bq_addr_e_t        *bq_e;
 1610         device_t                        dev = ha->pci_dev;
 1611 
 1612         ha->rx_ring[ridx].cq_dma.alignment = 128;
 1613         ha->rx_ring[ridx].cq_dma.size =
 1614                 (NUM_CQ_ENTRIES * (sizeof (q81_cq_e_t))) + PAGE_SIZE;
 1615 
 1616         ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].cq_dma);
 1617 
 1618         if (ret) {
 1619                 device_printf(dev, "%s: [%d] cq failed\n", __func__, ridx);
 1620                 goto qls_alloc_rx_ring_dma_exit;
 1621         }
 1622         ha->rx_ring[ridx].flags.cq_dma = 1;
 1623 
 1624         ha->rx_ring[ridx].lbq_dma.alignment = 8;
 1625         ha->rx_ring[ridx].lbq_dma.size = QLA_LGBQ_AND_TABLE_SIZE;
 1626 
 1627         ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].lbq_dma);
 1628 
 1629         if (ret) {
 1630                 device_printf(dev, "%s: [%d] lbq failed\n", __func__, ridx);
 1631                 goto qls_alloc_rx_ring_dma_exit;
 1632         }
 1633         ha->rx_ring[ridx].flags.lbq_dma = 1;
 1634 
 1635         ha->rx_ring[ridx].sbq_dma.alignment = 8;
 1636         ha->rx_ring[ridx].sbq_dma.size = QLA_SMBQ_AND_TABLE_SIZE;
 1637 
 1638         ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].sbq_dma);
 1639 
 1640         if (ret) {
 1641                 device_printf(dev, "%s: [%d] sbq failed\n", __func__, ridx);
 1642                 goto qls_alloc_rx_ring_dma_exit;
 1643         }
 1644         ha->rx_ring[ridx].flags.sbq_dma = 1;
 1645 
 1646         ha->rx_ring[ridx].lb_dma.alignment = 8;
 1647         ha->rx_ring[ridx].lb_dma.size = (QLA_LGB_SIZE * QLA_NUM_LGB_ENTRIES);
 1648 
 1649         ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].lb_dma);
 1650         if (ret) {
 1651                 device_printf(dev, "%s: [%d] lb failed\n", __func__, ridx);
 1652                 goto qls_alloc_rx_ring_dma_exit;
 1653         }
 1654         ha->rx_ring[ridx].flags.lb_dma = 1;
 1655 
 1656         bzero(ha->rx_ring[ridx].cq_dma.dma_b, ha->rx_ring[ridx].cq_dma.size);
 1657         bzero(ha->rx_ring[ridx].lbq_dma.dma_b, ha->rx_ring[ridx].lbq_dma.size);
 1658         bzero(ha->rx_ring[ridx].sbq_dma.dma_b, ha->rx_ring[ridx].sbq_dma.size);
 1659         bzero(ha->rx_ring[ridx].lb_dma.dma_b, ha->rx_ring[ridx].lb_dma.size);
 1660 
 1661         /* completion queue */
 1662         ha->rx_ring[ridx].cq_base_vaddr = ha->rx_ring[ridx].cq_dma.dma_b;
 1663         ha->rx_ring[ridx].cq_base_paddr = ha->rx_ring[ridx].cq_dma.dma_addr;
 1664 
 1665         v_addr = ha->rx_ring[ridx].cq_dma.dma_b;
 1666         p_addr = ha->rx_ring[ridx].cq_dma.dma_addr;
 1667 
 1668         v_addr = v_addr + (NUM_CQ_ENTRIES * (sizeof (q81_cq_e_t)));
 1669         p_addr = p_addr + (NUM_CQ_ENTRIES * (sizeof (q81_cq_e_t)));
 1670 
 1671         /* completion queue icb */
 1672         ha->rx_ring[ridx].cq_icb_vaddr = v_addr;
 1673         ha->rx_ring[ridx].cq_icb_paddr = p_addr;
 1674 
 1675         v_addr = v_addr + (PAGE_SIZE >> 2);
 1676         p_addr = p_addr + (PAGE_SIZE >> 2);
 1677 
 1678         /* completion queue index register */
 1679         ha->rx_ring[ridx].cqi_vaddr = (uint32_t *)v_addr;
 1680         ha->rx_ring[ridx].cqi_paddr = p_addr;
 1681 
 1682         v_addr = ha->rx_ring[ridx].lbq_dma.dma_b;
 1683         p_addr = ha->rx_ring[ridx].lbq_dma.dma_addr;
 1684 
 1685         /* large buffer queue address table */
 1686         ha->rx_ring[ridx].lbq_addr_tbl_vaddr = v_addr;
 1687         ha->rx_ring[ridx].lbq_addr_tbl_paddr = p_addr;
 1688 
 1689         /* large buffer queue */
 1690         ha->rx_ring[ridx].lbq_vaddr = v_addr + PAGE_SIZE;
 1691         ha->rx_ring[ridx].lbq_paddr = p_addr + PAGE_SIZE;
 1692         
 1693         v_addr = ha->rx_ring[ridx].sbq_dma.dma_b;
 1694         p_addr = ha->rx_ring[ridx].sbq_dma.dma_addr;
 1695 
 1696         /* small buffer queue address table */
 1697         ha->rx_ring[ridx].sbq_addr_tbl_vaddr = v_addr;
 1698         ha->rx_ring[ridx].sbq_addr_tbl_paddr = p_addr;
 1699 
 1700         /* small buffer queue */
 1701         ha->rx_ring[ridx].sbq_vaddr = v_addr + PAGE_SIZE;
 1702         ha->rx_ring[ridx].sbq_paddr = p_addr + PAGE_SIZE;
 1703 
 1704         ha->rx_ring[ridx].lb_vaddr = ha->rx_ring[ridx].lb_dma.dma_b;
 1705         ha->rx_ring[ridx].lb_paddr = ha->rx_ring[ridx].lb_dma.dma_addr;
 1706 
 1707         /* Initialize Large Buffer Queue Table */
 1708 
 1709         p_addr = ha->rx_ring[ridx].lbq_paddr;
 1710         bq_e = ha->rx_ring[ridx].lbq_addr_tbl_vaddr;
 1711 
 1712         bq_e->addr_lo = p_addr & 0xFFFFFFFF;
 1713         bq_e->addr_hi = (p_addr >> 32) & 0xFFFFFFFF;
 1714 
 1715         p_addr = ha->rx_ring[ridx].lb_paddr;
 1716         bq_e = ha->rx_ring[ridx].lbq_vaddr;
 1717 
 1718         for (i = 0; i < QLA_NUM_LGB_ENTRIES; i++) {
 1719                 bq_e->addr_lo = p_addr & 0xFFFFFFFF;
 1720                 bq_e->addr_hi = (p_addr >> 32) & 0xFFFFFFFF;
 1721 
 1722                 p_addr = p_addr + QLA_LGB_SIZE;
 1723                 bq_e++;
 1724         }
 1725 
 1726         /* Initialize Small Buffer Queue Table */
 1727 
 1728         p_addr = ha->rx_ring[ridx].sbq_paddr;
 1729         bq_e = ha->rx_ring[ridx].sbq_addr_tbl_vaddr;
 1730 
 1731         for (i =0; i < (QLA_SBQ_SIZE/QLA_PAGE_SIZE); i++) {
 1732                 bq_e->addr_lo = p_addr & 0xFFFFFFFF;
 1733                 bq_e->addr_hi = (p_addr >> 32) & 0xFFFFFFFF;
 1734 
 1735                 p_addr = p_addr + QLA_PAGE_SIZE;
 1736                 bq_e++;
 1737         }
 1738 
 1739 qls_alloc_rx_ring_dma_exit:
 1740         return (ret);
 1741 }
 1742 
 1743 static int
 1744 qls_alloc_rx_dma(qla_host_t *ha)
 1745 {
 1746         int     i;
 1747         int     ret = 0;
 1748 
 1749         if (bus_dma_tag_create(NULL,    /* parent */
 1750                         1, 0,    /* alignment, bounds */
 1751                         BUS_SPACE_MAXADDR,       /* lowaddr */
 1752                         BUS_SPACE_MAXADDR,       /* highaddr */
 1753                         NULL, NULL,      /* filter, filterarg */
 1754                         MJUM9BYTES,     /* maxsize */
 1755                         1,        /* nsegments */
 1756                         MJUM9BYTES,        /* maxsegsize */
 1757                         BUS_DMA_ALLOCNOW,        /* flags */
 1758                         NULL,    /* lockfunc */
 1759                         NULL,    /* lockfuncarg */
 1760                         &ha->rx_tag)) {
 1761 
 1762                 device_printf(ha->pci_dev, "%s: rx_tag alloc failed\n",
 1763                         __func__);
 1764 
 1765                 return (ENOMEM);
 1766         }
 1767 
 1768         for (i = 0; i < ha->num_rx_rings; i++) {
 1769                 ret = qls_alloc_rx_ring_dma(ha, i);
 1770 
 1771                 if (ret) {
 1772                         qls_free_rx_dma(ha);
 1773                         break;
 1774                 }
 1775         }
 1776 
 1777         return (ret);
 1778 }
 1779 
 1780 static int
 1781 qls_wait_for_flash_ready(qla_host_t *ha)
 1782 {
 1783         uint32_t data32;
 1784         uint32_t count = 3;
 1785 
 1786         while (count--) {
 1787 
 1788                 data32 = READ_REG32(ha, Q81_CTL_FLASH_ADDR);
 1789 
 1790                 if (data32 & Q81_CTL_FLASH_ADDR_ERR)
 1791                         goto qls_wait_for_flash_ready_exit;
 1792                 
 1793                 if (data32 & Q81_CTL_FLASH_ADDR_RDY)
 1794                         return (0);
 1795 
 1796                 QLA_USEC_DELAY(100);
 1797         }
 1798 
 1799 qls_wait_for_flash_ready_exit:
 1800         QL_DPRINT1((ha->pci_dev, "%s: failed\n", __func__));
 1801 
 1802         return (-1);
 1803 }
 1804 
 1805 /*
 1806  * Name: qls_rd_flash32
 1807  * Function: Read Flash Memory
 1808  */
 1809 int
 1810 qls_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data)
 1811 {
 1812         int ret;
 1813 
 1814         ret = qls_wait_for_flash_ready(ha);
 1815 
 1816         if (ret)
 1817                 return (ret);
 1818 
 1819         WRITE_REG32(ha, Q81_CTL_FLASH_ADDR, (addr | Q81_CTL_FLASH_ADDR_R));
 1820 
 1821         ret = qls_wait_for_flash_ready(ha);
 1822 
 1823         if (ret)
 1824                 return (ret);
 1825 
 1826         *data = READ_REG32(ha, Q81_CTL_FLASH_DATA);
 1827 
 1828         return 0;
 1829 }
 1830 
 1831 static int
 1832 qls_flash_validate(qla_host_t *ha, const char *signature)
 1833 {
 1834         uint16_t csum16 = 0;
 1835         uint16_t *data16;
 1836         int i;
 1837 
 1838         if (bcmp(ha->flash.id, signature, 4)) {
 1839                 QL_DPRINT1((ha->pci_dev, "%s: invalid signature "
 1840                         "%x:%x:%x:%x %s\n", __func__, ha->flash.id[0],
 1841                         ha->flash.id[1], ha->flash.id[2], ha->flash.id[3],
 1842                         signature));
 1843                 return(-1);
 1844         }
 1845 
 1846         data16 = (uint16_t *)&ha->flash;
 1847 
 1848         for (i = 0; i < (sizeof (q81_flash_t) >> 1); i++) {
 1849                 csum16 += *data16++;
 1850         }
 1851 
 1852         if (csum16) {
 1853                 QL_DPRINT1((ha->pci_dev, "%s: invalid checksum\n", __func__));
 1854                 return(-1);
 1855         }
 1856         return(0);
 1857 }
 1858 
 1859 int
 1860 qls_rd_nic_params(qla_host_t *ha)
 1861 {
 1862         int             i, ret = 0;
 1863         uint32_t        faddr;
 1864         uint32_t        *qflash;
 1865 
 1866         if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_FLASH, Q81_CTL_SEM_SET_FLASH)) {
 1867                 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__));
 1868                 return(-1);
 1869         }
 1870 
 1871         if ((ha->pci_func & 0x1) == 0)
 1872                 faddr = Q81_F0_FLASH_OFFSET >> 2;
 1873         else
 1874                 faddr = Q81_F1_FLASH_OFFSET >> 2;
 1875 
 1876         qflash = (uint32_t *)&ha->flash;
 1877 
 1878         for (i = 0; i < (sizeof(q81_flash_t) >> 2) ; i++) {
 1879 
 1880                 ret = qls_rd_flash32(ha, faddr, qflash);
 1881 
 1882                 if (ret)
 1883                         goto qls_rd_flash_data_exit;
 1884 
 1885                 faddr++;
 1886                 qflash++;
 1887         }
 1888 
 1889         QL_DUMP_BUFFER8(ha, __func__, (&ha->flash), (sizeof (q81_flash_t)));
 1890 
 1891         ret = qls_flash_validate(ha, Q81_FLASH_ID);
 1892 
 1893         if (ret)
 1894                 goto qls_rd_flash_data_exit;
 1895 
 1896         bcopy(ha->flash.mac_addr0, ha->mac_addr, ETHER_ADDR_LEN);
 1897 
 1898         QL_DPRINT1((ha->pci_dev, "%s: mac %02x:%02x:%02x:%02x:%02x:%02x\n",
 1899                 __func__, ha->mac_addr[0],  ha->mac_addr[1], ha->mac_addr[2],
 1900                 ha->mac_addr[3], ha->mac_addr[4],  ha->mac_addr[5]));
 1901 
 1902 qls_rd_flash_data_exit:
 1903 
 1904         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_FLASH);
 1905 
 1906         return(ret);
 1907 }
 1908 
 1909 static int
 1910 qls_sem_lock(qla_host_t *ha, uint32_t mask, uint32_t value)
 1911 {
 1912         uint32_t count = 30;
 1913         uint32_t data;
 1914 
 1915         while (count--) {
 1916                 WRITE_REG32(ha, Q81_CTL_SEMAPHORE, (mask|value));
 1917         
 1918                 data = READ_REG32(ha, Q81_CTL_SEMAPHORE);
 1919 
 1920                 if (data & value) {
 1921                         return (0);
 1922                 } else {
 1923                         QLA_USEC_DELAY(100);
 1924                 }
 1925         }
 1926         ha->qla_initiate_recovery = 1;
 1927         return (-1);
 1928 }
 1929 
 1930 static void
 1931 qls_sem_unlock(qla_host_t *ha, uint32_t mask)
 1932 {
 1933         WRITE_REG32(ha, Q81_CTL_SEMAPHORE, mask);
 1934 }
 1935 
 1936 static int
 1937 qls_wait_for_proc_addr_ready(qla_host_t *ha)
 1938 {
 1939         uint32_t data32;
 1940         uint32_t count = 3;
 1941 
 1942         while (count--) {
 1943 
 1944                 data32 = READ_REG32(ha, Q81_CTL_PROC_ADDR);
 1945 
 1946                 if (data32 & Q81_CTL_PROC_ADDR_ERR)
 1947                         goto qls_wait_for_proc_addr_ready_exit;
 1948                 
 1949                 if (data32 & Q81_CTL_PROC_ADDR_RDY)
 1950                         return (0);
 1951 
 1952                 QLA_USEC_DELAY(100);
 1953         }
 1954 
 1955 qls_wait_for_proc_addr_ready_exit:
 1956         QL_DPRINT1((ha->pci_dev, "%s: failed\n", __func__));
 1957 
 1958         ha->qla_initiate_recovery = 1;
 1959         return (-1);
 1960 }
 1961 
 1962 static int
 1963 qls_proc_addr_rd_reg(qla_host_t *ha, uint32_t addr_module, uint32_t reg,
 1964         uint32_t *data)
 1965 {
 1966         int ret;
 1967         uint32_t value;
 1968 
 1969         ret = qls_wait_for_proc_addr_ready(ha);
 1970 
 1971         if (ret)
 1972                 goto qls_proc_addr_rd_reg_exit;
 1973 
 1974         value = addr_module | reg | Q81_CTL_PROC_ADDR_READ;
 1975 
 1976         WRITE_REG32(ha, Q81_CTL_PROC_ADDR, value);
 1977 
 1978         ret = qls_wait_for_proc_addr_ready(ha);
 1979 
 1980         if (ret)
 1981                 goto qls_proc_addr_rd_reg_exit;
 1982         
 1983         *data = READ_REG32(ha, Q81_CTL_PROC_DATA); 
 1984 
 1985 qls_proc_addr_rd_reg_exit:
 1986         return (ret);
 1987 }
 1988 
 1989 static int
 1990 qls_proc_addr_wr_reg(qla_host_t *ha, uint32_t addr_module, uint32_t reg,
 1991         uint32_t data)
 1992 {
 1993         int ret;
 1994         uint32_t value;
 1995 
 1996         ret = qls_wait_for_proc_addr_ready(ha);
 1997 
 1998         if (ret)
 1999                 goto qls_proc_addr_wr_reg_exit;
 2000 
 2001         WRITE_REG32(ha, Q81_CTL_PROC_DATA, data);
 2002 
 2003         value = addr_module | reg;
 2004 
 2005         WRITE_REG32(ha, Q81_CTL_PROC_ADDR, value);
 2006 
 2007         ret = qls_wait_for_proc_addr_ready(ha);
 2008 
 2009 qls_proc_addr_wr_reg_exit:
 2010         return (ret);
 2011 }
 2012 
 2013 static int
 2014 qls_hw_nic_reset(qla_host_t *ha)
 2015 {
 2016         int             count;
 2017         uint32_t        data;
 2018         device_t        dev = ha->pci_dev;
 2019         
 2020         ha->hw_init = 0;
 2021 
 2022         data = (Q81_CTL_RESET_FUNC << Q81_CTL_RESET_MASK_SHIFT) |
 2023                         Q81_CTL_RESET_FUNC;
 2024         WRITE_REG32(ha, Q81_CTL_RESET, data);
 2025 
 2026         count = 10;
 2027         while (count--) {
 2028                 data = READ_REG32(ha, Q81_CTL_RESET);
 2029                 if ((data & Q81_CTL_RESET_FUNC) == 0)
 2030                         break;
 2031                 QLA_USEC_DELAY(10);
 2032         }
 2033         if (count == 0) {
 2034                 device_printf(dev, "%s: Bit 15 not cleared after Reset\n",
 2035                         __func__);
 2036                 return (-1);
 2037         }
 2038         return (0);
 2039 }
 2040         
 2041 static int
 2042 qls_hw_reset(qla_host_t *ha)
 2043 {
 2044         device_t        dev = ha->pci_dev;
 2045         int             ret;
 2046         int             count;
 2047         uint32_t        data;
 2048 
 2049         QL_DPRINT2((ha->pci_dev, "%s:enter[%d]\n", __func__, ha->hw_init));
 2050 
 2051         if (ha->hw_init == 0) {
 2052                 ret = qls_hw_nic_reset(ha);
 2053                 goto qls_hw_reset_exit;
 2054         }
 2055 
 2056         ret = qls_clear_routing_table(ha);
 2057         if (ret) 
 2058                 goto qls_hw_reset_exit;
 2059 
 2060         ret = qls_mbx_set_mgmt_ctrl(ha, Q81_MBX_SET_MGMT_CTL_STOP);
 2061         if (ret) 
 2062                 goto qls_hw_reset_exit;
 2063 
 2064         /*
 2065          * Wait for FIFO to empty
 2066          */
 2067         count = 5;
 2068         while (count--) {
 2069                 data = READ_REG32(ha, Q81_CTL_STATUS);
 2070                 if (data & Q81_CTL_STATUS_NFE)
 2071                         break;
 2072                 qls_mdelay(__func__, 100);
 2073         }
 2074         if (count == 0) {
 2075                 device_printf(dev, "%s: NFE bit not set\n", __func__);
 2076                 goto qls_hw_reset_exit;
 2077         }
 2078 
 2079         count = 5;
 2080         while (count--) {
 2081                 (void)qls_mbx_get_mgmt_ctrl(ha, &data);
 2082 
 2083                 if ((data & Q81_MBX_GET_MGMT_CTL_FIFO_EMPTY) &&
 2084                         (data & Q81_MBX_GET_MGMT_CTL_SET_MGMT))
 2085                         break;
 2086                 qls_mdelay(__func__, 100);
 2087         }
 2088         if (count == 0)
 2089                 goto qls_hw_reset_exit;
 2090 
 2091         /*
 2092          * Reset the NIC function
 2093          */
 2094         ret = qls_hw_nic_reset(ha);
 2095         if (ret) 
 2096                 goto qls_hw_reset_exit;
 2097         
 2098         ret = qls_mbx_set_mgmt_ctrl(ha, Q81_MBX_SET_MGMT_CTL_RESUME);
 2099 
 2100 qls_hw_reset_exit:
 2101         if (ret)
 2102                 device_printf(dev, "%s: failed\n", __func__);
 2103                 
 2104         return (ret);
 2105 }
 2106 
 2107 /*
 2108  * MPI Related Functions
 2109  */
 2110 int
 2111 qls_mpi_risc_rd_reg(qla_host_t *ha, uint32_t reg, uint32_t *data)
 2112 {
 2113         int ret;
 2114 
 2115         ret = qls_proc_addr_rd_reg(ha, Q81_CTL_PROC_ADDR_MPI_RISC,
 2116                         reg, data);
 2117         return (ret);
 2118 }
 2119 
 2120 int
 2121 qls_mpi_risc_wr_reg(qla_host_t *ha, uint32_t reg, uint32_t data)
 2122 {
 2123         int ret;
 2124 
 2125         ret = qls_proc_addr_wr_reg(ha, Q81_CTL_PROC_ADDR_MPI_RISC,
 2126                         reg, data);
 2127         return (ret);
 2128 }
 2129 
 2130 int
 2131 qls_mbx_rd_reg(qla_host_t *ha, uint32_t reg, uint32_t *data)
 2132 {
 2133         int ret;
 2134 
 2135         if ((ha->pci_func & 0x1) == 0)
 2136                 reg += Q81_FUNC0_MBX_OUT_REG0;
 2137         else
 2138                 reg += Q81_FUNC1_MBX_OUT_REG0;
 2139 
 2140         ret = qls_mpi_risc_rd_reg(ha, reg, data);
 2141 
 2142         return (ret);
 2143 }
 2144 
 2145 int
 2146 qls_mbx_wr_reg(qla_host_t *ha, uint32_t reg, uint32_t data)
 2147 {
 2148         int ret;
 2149 
 2150         if ((ha->pci_func & 0x1) == 0)
 2151                 reg += Q81_FUNC0_MBX_IN_REG0;
 2152         else
 2153                 reg += Q81_FUNC1_MBX_IN_REG0;
 2154 
 2155         ret = qls_mpi_risc_wr_reg(ha, reg, data);
 2156 
 2157         return (ret);
 2158 }
 2159 
 2160 
 2161 static int
 2162 qls_mbx_cmd(qla_host_t *ha, uint32_t *in_mbx, uint32_t i_count,
 2163         uint32_t *out_mbx, uint32_t o_count)
 2164 {
 2165         int i, ret = -1;
 2166         uint32_t data32, mbx_cmd = 0;
 2167         uint32_t count = 50;
 2168 
 2169         QL_DPRINT2((ha->pci_dev, "%s: enter[0x%08x 0x%08x 0x%08x]\n",
 2170                 __func__, *in_mbx, *(in_mbx + 1), *(in_mbx + 2)));
 2171 
 2172         data32 = READ_REG32(ha, Q81_CTL_HOST_CMD_STATUS);
 2173 
 2174         if (data32 & Q81_CTL_HCS_HTR_INTR) {
 2175                 device_printf(ha->pci_dev, "%s: cmd_status[0x%08x]\n",
 2176                         __func__, data32);
 2177                 goto qls_mbx_cmd_exit;
 2178         }
 2179 
 2180         if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_PROC_ADDR_NIC_RCV,
 2181                 Q81_CTL_SEM_SET_PROC_ADDR_NIC_RCV)) {
 2182                 device_printf(ha->pci_dev, "%s: semlock failed\n", __func__);
 2183                 goto qls_mbx_cmd_exit;
 2184         }
 2185 
 2186         ha->mbx_done = 0;
 2187 
 2188         mbx_cmd = *in_mbx;
 2189 
 2190         for (i = 0; i < i_count; i++) {
 2191 
 2192                 ret = qls_mbx_wr_reg(ha, i, *in_mbx);
 2193 
 2194                 if (ret) {
 2195                         device_printf(ha->pci_dev,
 2196                                 "%s: mbx_wr[%d, 0x%08x] failed\n", __func__,
 2197                                 i, *in_mbx);
 2198                         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_PROC_ADDR_NIC_RCV);
 2199                         goto qls_mbx_cmd_exit;
 2200                 }
 2201 
 2202                 in_mbx++;
 2203         }
 2204         WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS, Q81_CTL_HCS_CMD_SET_HTR_INTR);
 2205 
 2206         qls_sem_unlock(ha, Q81_CTL_SEM_MASK_PROC_ADDR_NIC_RCV);
 2207 
 2208         ret = -1;
 2209         ha->mbx_done = 0;
 2210 
 2211         while (count--) {
 2212 
 2213                 if (ha->flags.intr_enable == 0) {
 2214                         data32 = READ_REG32(ha, Q81_CTL_STATUS);
 2215 
 2216                         if (!(data32 & Q81_CTL_STATUS_PI)) {
 2217                                 qls_mdelay(__func__, 100);
 2218                                 continue;
 2219                         }
 2220 
 2221                         ret = qls_mbx_rd_reg(ha, 0, &data32);
 2222 
 2223                         if (ret == 0 ) {
 2224                                 if ((data32 & 0xF000) == 0x4000) {
 2225 
 2226                                         out_mbx[0] = data32;
 2227 
 2228                                         for (i = 1; i < o_count; i++) {
 2229                                                 ret = qls_mbx_rd_reg(ha, i,
 2230                                                                 &data32);
 2231                                                 if (ret) {
 2232                                                         device_printf(
 2233                                                                 ha->pci_dev,
 2234                                                                 "%s: mbx_rd[%d]"
 2235                                                                 " failed\n",
 2236                                                                 __func__, i);
 2237                                                         break;
 2238                                                 }
 2239                                                 out_mbx[i] = data32;
 2240                                         }
 2241                                         break;
 2242                                 } else if ((data32 & 0xF000) == 0x8000) {
 2243                                         count = 50;
 2244                                         WRITE_REG32(ha,\
 2245                                                 Q81_CTL_HOST_CMD_STATUS,\
 2246                                                 Q81_CTL_HCS_CMD_CLR_RTH_INTR);
 2247                                 }
 2248                         }
 2249                 } else {
 2250                         if (ha->mbx_done) {
 2251                                 for (i = 1; i < o_count; i++) {
 2252                                         out_mbx[i] = ha->mbox[i];
 2253                                 }
 2254                                 ret = 0;
 2255                                 break;
 2256                         }
 2257                 }
 2258                 qls_mdelay(__func__, 1000);
 2259         }
 2260 
 2261 qls_mbx_cmd_exit:
 2262 
 2263         if (ha->flags.intr_enable == 0) {
 2264                 WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS,\
 2265                         Q81_CTL_HCS_CMD_CLR_RTH_INTR);
 2266         }
 2267 
 2268         if (ret) {
 2269                 ha->qla_initiate_recovery = 1;
 2270         }
 2271 
 2272         QL_DPRINT2((ha->pci_dev, "%s: exit[%d]\n", __func__, ret));
 2273         return (ret);
 2274 }
 2275 
 2276 static int
 2277 qls_mbx_set_mgmt_ctrl(qla_host_t *ha, uint32_t t_ctrl)
 2278 {
 2279         uint32_t *mbox;
 2280         device_t dev = ha->pci_dev;
 2281 
 2282         mbox = ha->mbox;
 2283         bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
 2284 
 2285         mbox[0] = Q81_MBX_SET_MGMT_CTL;
 2286         mbox[1] = t_ctrl;
 2287 
 2288         if (qls_mbx_cmd(ha, mbox, 2, mbox, 1)) {
 2289                 device_printf(dev, "%s failed\n", __func__);
 2290                 return (-1);
 2291         }
 2292 
 2293         if ((mbox[0] == Q81_MBX_CMD_COMPLETE) ||
 2294                 ((t_ctrl == Q81_MBX_SET_MGMT_CTL_STOP) &&
 2295                         (mbox[0] == Q81_MBX_CMD_ERROR))){
 2296                 return (0);
 2297         }
 2298         device_printf(dev, "%s failed [0x%08x]\n", __func__, mbox[0]);
 2299         return (-1);
 2300 
 2301 }
 2302 
 2303 static int
 2304 qls_mbx_get_mgmt_ctrl(qla_host_t *ha, uint32_t *t_status)
 2305 {
 2306         uint32_t *mbox;
 2307         device_t dev = ha->pci_dev;
 2308 
 2309         *t_status = 0;
 2310 
 2311         mbox = ha->mbox;
 2312         bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
 2313 
 2314         mbox[0] = Q81_MBX_GET_MGMT_CTL;
 2315 
 2316         if (qls_mbx_cmd(ha, mbox, 1, mbox, 2)) {
 2317                 device_printf(dev, "%s failed\n", __func__);
 2318                 return (-1);
 2319         }
 2320 
 2321         *t_status = mbox[1];
 2322 
 2323         return (0);
 2324 }
 2325 
 2326 static void
 2327 qls_mbx_get_link_status(qla_host_t *ha)
 2328 {
 2329         uint32_t *mbox;
 2330         device_t dev = ha->pci_dev;
 2331 
 2332         mbox = ha->mbox;
 2333         bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
 2334 
 2335         mbox[0] = Q81_MBX_GET_LNK_STATUS;
 2336 
 2337         if (qls_mbx_cmd(ha, mbox, 1, mbox, 6)) {
 2338                 device_printf(dev, "%s failed\n", __func__);
 2339                 return;
 2340         }
 2341 
 2342         ha->link_status                 = mbox[1];
 2343         ha->link_down_info              = mbox[2];
 2344         ha->link_hw_info                = mbox[3];
 2345         ha->link_dcbx_counters          = mbox[4];
 2346         ha->link_change_counters        = mbox[5];
 2347 
 2348         device_printf(dev, "%s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
 2349                 __func__, mbox[0],mbox[1],mbox[2],mbox[3],mbox[4],mbox[5]);
 2350 
 2351         return;
 2352 }
 2353 
 2354 static void
 2355 qls_mbx_about_fw(qla_host_t *ha)
 2356 {
 2357         uint32_t *mbox;
 2358         device_t dev = ha->pci_dev;
 2359 
 2360         mbox = ha->mbox;
 2361         bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
 2362 
 2363         mbox[0] = Q81_MBX_ABOUT_FW;
 2364 
 2365         if (qls_mbx_cmd(ha, mbox, 1, mbox, 6)) {
 2366                 device_printf(dev, "%s failed\n", __func__);
 2367                 return;
 2368         }
 2369 
 2370         device_printf(dev, "%s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
 2371                 __func__, mbox[0],mbox[1],mbox[2],mbox[3],mbox[4],mbox[5]);
 2372 }
 2373 
 2374 int
 2375 qls_mbx_dump_risc_ram(qla_host_t *ha, void *buf, uint32_t r_addr,
 2376         uint32_t r_size)
 2377 {
 2378         bus_addr_t b_paddr;
 2379         uint32_t *mbox;
 2380         device_t dev = ha->pci_dev;
 2381 
 2382         mbox = ha->mbox;
 2383         bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS));
 2384 
 2385         bzero(ha->mpi_dma.dma_b,(r_size << 2));
 2386         b_paddr = ha->mpi_dma.dma_addr;
 2387 
 2388         mbox[0] = Q81_MBX_DUMP_RISC_RAM;
 2389         mbox[1] = r_addr & 0xFFFF;
 2390         mbox[2] = ((uint32_t)(b_paddr >> 16)) & 0xFFFF;
 2391         mbox[3] = ((uint32_t)b_paddr) & 0xFFFF;
 2392         mbox[4] = (r_size >> 16) & 0xFFFF;
 2393         mbox[5] = r_size & 0xFFFF;
 2394         mbox[6] = ((uint32_t)(b_paddr >> 48)) & 0xFFFF;
 2395         mbox[7] = ((uint32_t)(b_paddr >> 32)) & 0xFFFF;
 2396         mbox[8] = (r_addr >> 16) & 0xFFFF;
 2397 
 2398         bus_dmamap_sync(ha->mpi_dma.dma_tag, ha->mpi_dma.dma_map,
 2399                 BUS_DMASYNC_PREREAD);
 2400 
 2401         if (qls_mbx_cmd(ha, mbox, 9, mbox, 1)) {
 2402                 device_printf(dev, "%s failed\n", __func__);
 2403                 return (-1);
 2404         }
 2405         if (mbox[0] != 0x4000) {
 2406                 device_printf(ha->pci_dev, "%s: failed!\n", __func__);
 2407                 return (-1);
 2408         } else {
 2409                 bus_dmamap_sync(ha->mpi_dma.dma_tag, ha->mpi_dma.dma_map,
 2410                         BUS_DMASYNC_POSTREAD);
 2411                 bcopy(ha->mpi_dma.dma_b, buf, (r_size << 2));
 2412         }
 2413 
 2414         return (0);
 2415 }
 2416 
 2417 int 
 2418 qls_mpi_reset(qla_host_t *ha)
 2419 {
 2420         int             count;
 2421         uint32_t        data;
 2422         device_t        dev = ha->pci_dev;
 2423         
 2424         WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS,\
 2425                 Q81_CTL_HCS_CMD_SET_RISC_RESET);
 2426 
 2427         count = 10;
 2428         while (count--) {
 2429                 data = READ_REG32(ha, Q81_CTL_HOST_CMD_STATUS);
 2430                 if (data & Q81_CTL_HCS_RISC_RESET) {
 2431                         WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS,\
 2432                                 Q81_CTL_HCS_CMD_CLR_RISC_RESET);
 2433                         break;
 2434                 }
 2435                 qls_mdelay(__func__, 10);
 2436         }
 2437         if (count == 0) {
 2438                 device_printf(dev, "%s: failed\n", __func__);
 2439                 return (-1);
 2440         }
 2441         return (0);
 2442 }
 2443         

Cache object: 5085c7282f8520fb254f187aaed15a18


[ 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.