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

Cache object: 7b3a476b30f557f6929c5423f6fe5a47


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