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/netif/oce/oce_mbox.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 Emulex
    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 are met:
    7  *
    8  * 1. Redistributions of source code must retain the above copyright notice,
    9  *    this list of conditions and the following disclaimer.
   10  *
   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  * 3. Neither the name of the Emulex Corporation nor the names of its
   16  *    contributors may be used to endorse or promote products derived from
   17  *    this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  *
   31  * Contact Information:
   32  * freebsd-drivers@emulex.com
   33  *
   34  * Emulex
   35  * 3333 Susan Street
   36  * Costa Mesa, CA 92626
   37  */
   38 
   39 
   40 
   41 /* $FreeBSD: src/sys/dev/oce/oce_mbox.c,v 1.5 2013/07/07 00:30:13 svnexp Exp $ */
   42 
   43 
   44 #include "oce_if.h"
   45 extern uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
   46 
   47 /**
   48  * @brief Reset (firmware) common function
   49  * @param sc            software handle to the device
   50  * @returns             0 on success, ETIMEDOUT on failure
   51  */
   52 int
   53 oce_reset_fun(POCE_SOFTC sc)
   54 {
   55         struct oce_mbx *mbx;
   56         struct oce_bmbx *mb;
   57         struct ioctl_common_function_reset *fwcmd;
   58         int rc = 0;
   59 
   60         if (sc->flags & OCE_FLAGS_FUNCRESET_RQD) {
   61                 mb = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
   62                 mbx = &mb->mbx;
   63                 bzero(mbx, sizeof(struct oce_mbx));
   64 
   65                 fwcmd = (struct ioctl_common_function_reset *)&mbx->payload;
   66                 mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
   67                                         MBX_SUBSYSTEM_COMMON,
   68                                         OPCODE_COMMON_FUNCTION_RESET,
   69                                         10,     /* MBX_TIMEOUT_SEC */
   70                                         sizeof(struct
   71                                             ioctl_common_function_reset),
   72                                         OCE_MBX_VER_V0);
   73 
   74                 mbx->u0.s.embedded = 1;
   75                 mbx->payload_length =
   76                     sizeof(struct ioctl_common_function_reset);
   77 
   78                 rc = oce_mbox_dispatch(sc, 2);
   79         }
   80 
   81         return rc;
   82 }
   83 
   84 
   85 /**
   86  * @brief               This funtions tells firmware we are
   87  *                      done with commands.
   88  * @param sc            software handle to the device
   89  * @returns             0 on success, ETIMEDOUT on failure
   90  */
   91 int
   92 oce_fw_clean(POCE_SOFTC sc)
   93 {
   94         struct oce_bmbx *mbx;
   95         uint8_t *ptr;
   96         int ret = 0;
   97 
   98         mbx = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
   99         ptr = (uint8_t *) &mbx->mbx;
  100 
  101         /* Endian Signature */
  102         *ptr++ = 0xff;
  103         *ptr++ = 0xaa;
  104         *ptr++ = 0xbb;
  105         *ptr++ = 0xff;
  106         *ptr++ = 0xff;
  107         *ptr++ = 0xcc;
  108         *ptr++ = 0xdd;
  109         *ptr = 0xff;
  110 
  111         ret = oce_mbox_dispatch(sc, 2);
  112 
  113         return ret;
  114 }
  115 
  116 
  117 /**
  118  * @brief Mailbox wait
  119  * @param sc            software handle to the device
  120  * @param tmo_sec       timeout in seconds
  121  */
  122 static int
  123 oce_mbox_wait(POCE_SOFTC sc, uint32_t tmo_sec)
  124 {
  125         tmo_sec *= 10000;
  126         pd_mpu_mbox_db_t mbox_db;
  127 
  128         for (;;) {
  129                 if (tmo_sec != 0) {
  130                         if (--tmo_sec == 0)
  131                                 break;
  132                 }
  133 
  134                 mbox_db.dw0 = OCE_READ_REG32(sc, db, PD_MPU_MBOX_DB);
  135 
  136                 if (mbox_db.bits.ready)
  137                         return 0;
  138 
  139                 DELAY(100);
  140         }
  141 
  142         device_printf(sc->dev, "Mailbox timed out\n");
  143 
  144         return ETIMEDOUT;
  145 }
  146 
  147 
  148 /**
  149  * @brief Mailbox dispatch
  150  * @param sc            software handle to the device
  151  * @param tmo_sec       timeout in seconds
  152  */
  153 int
  154 oce_mbox_dispatch(POCE_SOFTC sc, uint32_t tmo_sec)
  155 {
  156         pd_mpu_mbox_db_t mbox_db;
  157         uint32_t pa;
  158         int rc;
  159 
  160         oce_dma_sync(&sc->bsmbx, BUS_DMASYNC_PREWRITE);
  161         pa = (uint32_t) ((uint64_t) sc->bsmbx.paddr >> 34);
  162         bzero(&mbox_db, sizeof(pd_mpu_mbox_db_t));
  163         mbox_db.bits.ready = 0;
  164         mbox_db.bits.hi = 1;
  165         mbox_db.bits.address = pa;
  166 
  167         rc = oce_mbox_wait(sc, tmo_sec);
  168         if (rc == 0) {
  169                 OCE_WRITE_REG32(sc, db, PD_MPU_MBOX_DB, mbox_db.dw0);
  170 
  171                 pa = (uint32_t) ((uint64_t) sc->bsmbx.paddr >> 4) & 0x3fffffff;
  172                 mbox_db.bits.ready = 0;
  173                 mbox_db.bits.hi = 0;
  174                 mbox_db.bits.address = pa;
  175 
  176                 rc = oce_mbox_wait(sc, tmo_sec);
  177 
  178                 if (rc == 0) {
  179                         OCE_WRITE_REG32(sc, db, PD_MPU_MBOX_DB, mbox_db.dw0);
  180 
  181                         rc = oce_mbox_wait(sc, tmo_sec);
  182 
  183                         oce_dma_sync(&sc->bsmbx, BUS_DMASYNC_POSTWRITE);
  184                 }
  185         }
  186 
  187         return rc;
  188 }
  189 
  190 
  191 
  192 /**
  193  * @brief               Mailbox common request header initialization
  194  * @param hdr           mailbox header
  195  * @param dom           domain
  196  * @param port          port
  197  * @param subsys        subsystem
  198  * @param opcode        opcode
  199  * @param timeout       timeout
  200  * @param pyld_len      payload length
  201  */
  202 void
  203 mbx_common_req_hdr_init(struct mbx_hdr *hdr,
  204                         uint8_t dom, uint8_t port,
  205                         uint8_t subsys, uint8_t opcode,
  206                         uint32_t timeout, uint32_t pyld_len,
  207                         uint8_t version)
  208 {
  209         hdr->u0.req.opcode = opcode;
  210         hdr->u0.req.subsystem = subsys;
  211         hdr->u0.req.port_number = port;
  212         hdr->u0.req.domain = dom;
  213 
  214         hdr->u0.req.timeout = timeout;
  215         hdr->u0.req.request_length = pyld_len - sizeof(struct mbx_hdr);
  216         hdr->u0.req.version = version;
  217 }
  218 
  219 
  220 
  221 /**
  222  * @brief Function to initialize the hw with host endian information
  223  * @param sc            software handle to the device
  224  * @returns             0 on success, ETIMEDOUT on failure
  225  */
  226 int
  227 oce_mbox_init(POCE_SOFTC sc)
  228 {
  229         struct oce_bmbx *mbx;
  230         uint8_t *ptr;
  231         int ret = 0;
  232 
  233         if (sc->flags & OCE_FLAGS_MBOX_ENDIAN_RQD) {
  234                 mbx = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
  235                 ptr = (uint8_t *) &mbx->mbx;
  236 
  237                 /* Endian Signature */
  238                 *ptr++ = 0xff;
  239                 *ptr++ = 0x12;
  240                 *ptr++ = 0x34;
  241                 *ptr++ = 0xff;
  242                 *ptr++ = 0xff;
  243                 *ptr++ = 0x56;
  244                 *ptr++ = 0x78;
  245                 *ptr = 0xff;
  246 
  247                 ret = oce_mbox_dispatch(sc, 0);
  248         }
  249 
  250         return ret;
  251 }
  252 
  253 
  254 /**
  255  * @brief               Function to get the firmware version
  256  * @param sc            software handle to the device
  257  * @returns             0 on success, EIO on failure
  258  */
  259 int
  260 oce_get_fw_version(POCE_SOFTC sc)
  261 {
  262         struct oce_mbx mbx;
  263         struct mbx_get_common_fw_version *fwcmd;
  264         int ret = 0;
  265 
  266         bzero(&mbx, sizeof(struct oce_mbx));
  267 
  268         fwcmd = (struct mbx_get_common_fw_version *)&mbx.payload;
  269         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  270                                 MBX_SUBSYSTEM_COMMON,
  271                                 OPCODE_COMMON_GET_FW_VERSION,
  272                                 MBX_TIMEOUT_SEC,
  273                                 sizeof(struct mbx_get_common_fw_version),
  274                                 OCE_MBX_VER_V0);
  275 
  276         mbx.u0.s.embedded = 1;
  277         mbx.payload_length = sizeof(struct mbx_get_common_fw_version);
  278         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
  279 
  280         ret = oce_mbox_post(sc, &mbx, NULL);
  281         if (!ret)
  282                 ret = fwcmd->hdr.u0.rsp.status;
  283         if (ret) {
  284                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  285                               __FUNCTION__, ret);
  286                 goto error;
  287         }
  288 
  289         bcopy(fwcmd->params.rsp.fw_ver_str, sc->fw_version, 32);
  290 error:
  291         return ret;
  292 }
  293 
  294 
  295 /**
  296  * @brief       Firmware will send gracious notifications during
  297  *              attach only after sending first mcc commnad. We
  298  *              use MCC queue only for getting async and mailbox
  299  *              for sending cmds. So to get gracious notifications
  300  *              atleast send one dummy command on mcc.
  301  */
  302 int
  303 oce_first_mcc_cmd(POCE_SOFTC sc)
  304 {
  305         struct oce_mbx *mbx;
  306         struct oce_mq *mq = sc->mq;
  307         struct mbx_get_common_fw_version *fwcmd;
  308         uint32_t reg_value;
  309 
  310         mbx = RING_GET_PRODUCER_ITEM_VA(mq->ring, struct oce_mbx);
  311         bzero(mbx, sizeof(struct oce_mbx));
  312 
  313         fwcmd = (struct mbx_get_common_fw_version *)&mbx->payload;
  314         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  315                                 MBX_SUBSYSTEM_COMMON,
  316                                 OPCODE_COMMON_GET_FW_VERSION,
  317                                 MBX_TIMEOUT_SEC,
  318                                 sizeof(struct mbx_get_common_fw_version),
  319                                 OCE_MBX_VER_V0);
  320         mbx->u0.s.embedded = 1;
  321         mbx->payload_length = sizeof(struct mbx_get_common_fw_version);
  322         bus_dmamap_sync(mq->ring->dma.tag, mq->ring->dma.map,
  323                                 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  324         RING_PUT(mq->ring, 1);
  325         reg_value = (1 << 16) | mq->mq_id;
  326         OCE_WRITE_REG32(sc, db, PD_MQ_DB, reg_value);
  327 
  328         return 0;
  329 }
  330 
  331 /**
  332  * @brief               Function to post a MBX to the mbox
  333  * @param sc            software handle to the device
  334  * @param mbx           pointer to the MBX to send
  335  * @param mbxctx        pointer to the mbx context structure
  336  * @returns             0 on success, error on failure
  337  */
  338 int
  339 oce_mbox_post(POCE_SOFTC sc, struct oce_mbx *mbx, struct oce_mbx_ctx *mbxctx)
  340 {
  341         struct oce_mbx *mb_mbx = NULL;
  342         struct oce_mq_cqe *mb_cqe = NULL;
  343         struct oce_bmbx *mb = NULL;
  344         int rc = 0;
  345         uint32_t tmo = 0;
  346         uint32_t cstatus = 0;
  347         uint32_t xstatus = 0;
  348 
  349         LOCK(&sc->bmbx_lock);
  350 
  351         mb = OCE_DMAPTR(&sc->bsmbx, struct oce_bmbx);
  352         mb_mbx = &mb->mbx;
  353 
  354         /* get the tmo */
  355         tmo = mbx->tag[0];
  356         mbx->tag[0] = 0;
  357 
  358         /* copy mbx into mbox */
  359         bcopy(mbx, mb_mbx, sizeof(struct oce_mbx));
  360 
  361         /* now dispatch */
  362         rc = oce_mbox_dispatch(sc, tmo);
  363         if (rc == 0) {
  364                 /*
  365                  * the command completed successfully. Now get the
  366                  * completion queue entry
  367                  */
  368                 mb_cqe = &mb->cqe;
  369                 DW_SWAP(u32ptr(&mb_cqe->u0.dw[0]), sizeof(struct oce_mq_cqe));
  370 
  371                 /* copy mbox mbx back */
  372                 bcopy(mb_mbx, mbx, sizeof(struct oce_mbx));
  373 
  374                 /* pick up the mailbox status */
  375                 cstatus = mb_cqe->u0.s.completion_status;
  376                 xstatus = mb_cqe->u0.s.extended_status;
  377 
  378                 /*
  379                  * store the mbx context in the cqe tag section so that
  380                  * the upper layer handling the cqe can associate the mbx
  381                  * with the response
  382                  */
  383                 if (cstatus == 0 && mbxctx) {
  384                         /* save context */
  385                         mbxctx->mbx = mb_mbx;
  386                         bcopy(&mbxctx, mb_cqe->u0.s.mq_tag,
  387                                 sizeof(struct oce_mbx_ctx *));
  388                 }
  389         }
  390 
  391         UNLOCK(&sc->bmbx_lock);
  392 
  393         return rc;
  394 }
  395 
  396 /**
  397  * @brief Function to read the mac address associated with an interface
  398  * @param sc            software handle to the device
  399  * @param if_id         interface id to read the address from
  400  * @param perm          set to 1 if reading the factory mac address.
  401  *                      In this case if_id is ignored
  402  * @param type          type of the mac address, whether network or storage
  403  * @param[out] mac      [OUTPUT] pointer to a buffer containing the
  404  *                      mac address when the command succeeds.
  405  * @returns             0 on success, EIO on failure
  406  */
  407 int
  408 oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id,
  409                 uint8_t perm, uint8_t type, struct mac_address_format *mac)
  410 {
  411         struct oce_mbx mbx;
  412         struct mbx_query_common_iface_mac *fwcmd;
  413         int ret = 0;
  414 
  415         bzero(&mbx, sizeof(struct oce_mbx));
  416 
  417         fwcmd = (struct mbx_query_common_iface_mac *)&mbx.payload;
  418         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  419                                 MBX_SUBSYSTEM_COMMON,
  420                                 OPCODE_COMMON_QUERY_IFACE_MAC,
  421                                 MBX_TIMEOUT_SEC,
  422                                 sizeof(struct mbx_query_common_iface_mac),
  423                                 OCE_MBX_VER_V0);
  424 
  425         fwcmd->params.req.permanent = perm;
  426         if (!perm)
  427                 fwcmd->params.req.if_id = (uint16_t) if_id;
  428         else
  429                 fwcmd->params.req.if_id = 0;
  430 
  431         fwcmd->params.req.type = type;
  432 
  433         mbx.u0.s.embedded = 1;
  434         mbx.payload_length = sizeof(struct mbx_query_common_iface_mac);
  435         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
  436 
  437         ret = oce_mbox_post(sc, &mbx, NULL);
  438         if (!ret)
  439                 ret = fwcmd->hdr.u0.rsp.status;
  440         if (ret) {
  441                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  442                               __FUNCTION__, ret);
  443                 goto error;
  444         }
  445 
  446         /* copy the mac addres in the output parameter */
  447         mac->size_of_struct = fwcmd->params.rsp.mac.size_of_struct;
  448         bcopy(&fwcmd->params.rsp.mac.mac_addr[0], &mac->mac_addr[0],
  449                 mac->size_of_struct);
  450 error:
  451         return ret;
  452 }
  453 
  454 /**
  455  * @brief Function to query the fw attributes from the hw
  456  * @param sc            software handle to the device
  457  * @returns             0 on success, EIO on failure
  458  */
  459 int
  460 oce_get_fw_config(POCE_SOFTC sc)
  461 {
  462         struct oce_mbx mbx;
  463         struct mbx_common_query_fw_config *fwcmd;
  464         int ret = 0;
  465 
  466         bzero(&mbx, sizeof(struct oce_mbx));
  467 
  468         fwcmd = (struct mbx_common_query_fw_config *)&mbx.payload;
  469         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  470                                 MBX_SUBSYSTEM_COMMON,
  471                                 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
  472                                 MBX_TIMEOUT_SEC,
  473                                 sizeof(struct mbx_common_query_fw_config),
  474                                 OCE_MBX_VER_V0);
  475 
  476         mbx.u0.s.embedded = 1;
  477         mbx.payload_length = sizeof(struct mbx_common_query_fw_config);
  478         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
  479 
  480         ret = oce_mbox_post(sc, &mbx, NULL);
  481         if (!ret)
  482                 ret = fwcmd->hdr.u0.rsp.status;
  483         if (ret) {
  484                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  485                               __FUNCTION__, ret);
  486                 goto error;
  487         }
  488 
  489         DW_SWAP(u32ptr(fwcmd), sizeof(struct mbx_common_query_fw_config));
  490 
  491         sc->config_number = fwcmd->params.rsp.config_number;
  492         sc->asic_revision = fwcmd->params.rsp.asic_revision;
  493         sc->port_id       = fwcmd->params.rsp.port_id;
  494         sc->function_mode = fwcmd->params.rsp.function_mode;
  495         sc->function_caps = fwcmd->params.rsp.function_caps;
  496 
  497         if (fwcmd->params.rsp.ulp[0].ulp_mode & ULP_NIC_MODE) {
  498                 sc->max_tx_rings = fwcmd->params.rsp.ulp[0].nic_wq_tot;
  499                 sc->max_rx_rings = fwcmd->params.rsp.ulp[0].lro_rqid_tot;
  500         } else {
  501                 sc->max_tx_rings = fwcmd->params.rsp.ulp[1].nic_wq_tot;
  502                 sc->max_rx_rings = fwcmd->params.rsp.ulp[1].lro_rqid_tot;
  503         }
  504 
  505 error:
  506         return ret;
  507 
  508 }
  509 
  510 /**
  511  *
  512  * @brief function to create a device interface
  513  * @param sc            software handle to the device
  514  * @param cap_flags     capability flags
  515  * @param en_flags      enable capability flags
  516  * @param vlan_tag      optional vlan tag to associate with the if
  517  * @param mac_addr      pointer to a buffer containing the mac address
  518  * @param[out] if_id    [OUTPUT] pointer to an integer to hold the ID of the
  519  interface created
  520  * @returns             0 on success, EIO on failure
  521  */
  522 int
  523 oce_if_create(POCE_SOFTC sc,
  524                 uint32_t cap_flags,
  525                 uint32_t en_flags,
  526                 uint16_t vlan_tag,
  527                 uint8_t *mac_addr,
  528                 uint32_t *if_id)
  529 {
  530         struct oce_mbx mbx;
  531         struct mbx_create_common_iface *fwcmd;
  532         int rc = 0;
  533 
  534         bzero(&mbx, sizeof(struct oce_mbx));
  535 
  536         fwcmd = (struct mbx_create_common_iface *)&mbx.payload;
  537         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  538                                 MBX_SUBSYSTEM_COMMON,
  539                                 OPCODE_COMMON_CREATE_IFACE,
  540                                 MBX_TIMEOUT_SEC,
  541                                 sizeof(struct mbx_create_common_iface),
  542                                 OCE_MBX_VER_V0);
  543         DW_SWAP(u32ptr(&fwcmd->hdr), sizeof(struct mbx_hdr));
  544 
  545         fwcmd->params.req.version = 0;
  546         fwcmd->params.req.cap_flags = LE_32(cap_flags);
  547         fwcmd->params.req.enable_flags = LE_32(en_flags);
  548         if (mac_addr != NULL) {
  549                 bcopy(mac_addr, &fwcmd->params.req.mac_addr[0], 6);
  550                 fwcmd->params.req.vlan_tag.u0.normal.vtag = LE_16(vlan_tag);
  551                 fwcmd->params.req.mac_invalid = 0;
  552         } else {
  553                 fwcmd->params.req.mac_invalid = 1;
  554         }
  555 
  556         mbx.u0.s.embedded = 1;
  557         mbx.payload_length = sizeof(struct mbx_create_common_iface);
  558         DW_SWAP(u32ptr(&mbx), OCE_BMBX_RHDR_SZ);
  559 
  560         rc = oce_mbox_post(sc, &mbx, NULL);
  561         if (!rc)
  562                 rc = fwcmd->hdr.u0.rsp.status;
  563         if (rc) {
  564                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  565                               __FUNCTION__, rc);
  566                 goto error;
  567         }
  568 
  569         *if_id = LE_32(fwcmd->params.rsp.if_id);
  570 
  571         if (mac_addr != NULL)
  572                 sc->pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
  573 error:
  574         return rc;
  575 }
  576 
  577 /**
  578  * @brief               Function to delete an interface
  579  * @param sc            software handle to the device
  580  * @param if_id         ID of the interface to delete
  581  * @returns             0 on success, EIO on failure
  582  */
  583 int
  584 oce_if_del(POCE_SOFTC sc, uint32_t if_id)
  585 {
  586         struct oce_mbx mbx;
  587         struct mbx_destroy_common_iface *fwcmd;
  588         int rc = 0;
  589 
  590         bzero(&mbx, sizeof(struct oce_mbx));
  591 
  592         fwcmd = (struct mbx_destroy_common_iface *)&mbx.payload;
  593         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  594                                 MBX_SUBSYSTEM_COMMON,
  595                                 OPCODE_COMMON_DESTROY_IFACE,
  596                                 MBX_TIMEOUT_SEC,
  597                                 sizeof(struct mbx_destroy_common_iface),
  598                                 OCE_MBX_VER_V0);
  599 
  600         fwcmd->params.req.if_id = if_id;
  601 
  602         mbx.u0.s.embedded = 1;
  603         mbx.payload_length = sizeof(struct mbx_destroy_common_iface);
  604         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
  605 
  606         rc = oce_mbox_post(sc, &mbx, NULL);
  607         if (!rc)
  608                 rc = fwcmd->hdr.u0.rsp.status;
  609         if (rc)
  610                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  611                               __FUNCTION__, rc);
  612         return rc;
  613 }
  614 
  615 /**
  616  * @brief Function to send the mbx command to configure vlan
  617  * @param sc            software handle to the device
  618  * @param if_id         interface identifier index
  619  * @param vtag_arr      array of vlan tags
  620  * @param vtag_cnt      number of elements in array
  621  * @param untagged      boolean TRUE/FLASE
  622  * @param enable_promisc flag to enable/disable VLAN promiscuous mode
  623  * @returns             0 on success, EIO on failure
  624  */
  625 int
  626 oce_config_vlan(POCE_SOFTC sc,
  627                 uint32_t if_id,
  628                 struct normal_vlan *vtag_arr,
  629                 uint8_t vtag_cnt, uint32_t untagged, uint32_t enable_promisc)
  630 {
  631         struct oce_mbx mbx;
  632         struct mbx_common_config_vlan *fwcmd;
  633         int rc;
  634 
  635         bzero(&mbx, sizeof(struct oce_mbx));
  636         fwcmd = (struct mbx_common_config_vlan *)&mbx.payload;
  637 
  638         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  639                                 MBX_SUBSYSTEM_COMMON,
  640                                 OPCODE_COMMON_CONFIG_IFACE_VLAN,
  641                                 MBX_TIMEOUT_SEC,
  642                                 sizeof(struct mbx_common_config_vlan),
  643                                 OCE_MBX_VER_V0);
  644 
  645         fwcmd->params.req.if_id = (uint8_t) if_id;
  646         fwcmd->params.req.promisc = (uint8_t) enable_promisc;
  647         fwcmd->params.req.untagged = (uint8_t) untagged;
  648         fwcmd->params.req.num_vlans = vtag_cnt;
  649 
  650         if (!enable_promisc) {
  651                 bcopy(vtag_arr, fwcmd->params.req.tags.normal_vlans,
  652                         vtag_cnt * sizeof(struct normal_vlan));
  653         }
  654         mbx.u0.s.embedded = 1;
  655         mbx.payload_length = sizeof(struct mbx_common_config_vlan);
  656         DW_SWAP(u32ptr(&mbx), (OCE_BMBX_RHDR_SZ + mbx.payload_length));
  657 
  658         rc = oce_mbox_post(sc, &mbx, NULL);
  659         if (!rc)
  660                 rc = fwcmd->hdr.u0.rsp.status;
  661         if (rc)
  662                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  663                               __FUNCTION__, rc);
  664         return 0;
  665 
  666 }
  667 
  668 /**
  669  * @brief Function to set flow control capability in the hardware
  670  * @param sc            software handle to the device
  671  * @param flow_control  flow control flags to set
  672  * @returns             0 on success, EIO on failure
  673  */
  674 int
  675 oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control)
  676 {
  677         struct oce_mbx mbx;
  678         struct mbx_common_get_set_flow_control *fwcmd =
  679                 (struct mbx_common_get_set_flow_control *)&mbx.payload;
  680         int rc;
  681 
  682         bzero(&mbx, sizeof(struct oce_mbx));
  683 
  684         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  685                                 MBX_SUBSYSTEM_COMMON,
  686                                 OPCODE_COMMON_SET_FLOW_CONTROL,
  687                                 MBX_TIMEOUT_SEC,
  688                                 sizeof(struct mbx_common_get_set_flow_control),
  689                                 OCE_MBX_VER_V0);
  690 
  691         if (flow_control & OCE_FC_TX)
  692                 fwcmd->tx_flow_control = 1;
  693 
  694         if (flow_control & OCE_FC_RX)
  695                 fwcmd->rx_flow_control = 1;
  696 
  697         mbx.u0.s.embedded = 1;
  698         mbx.payload_length = sizeof(struct mbx_common_get_set_flow_control);
  699         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
  700 
  701         rc = oce_mbox_post(sc, &mbx, NULL);
  702         if (!rc)
  703                 rc = fwcmd->hdr.u0.rsp.status;
  704         if (rc)
  705                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  706                               __FUNCTION__, rc);
  707         return rc;
  708 }
  709 
  710 /**
  711  * @brief Initialize the RSS CPU indirection table
  712  *
  713  * The table is used to choose the queue to place the incomming packets.
  714  * Incomming packets are hashed.  The lowest bits in the hash result
  715  * are used as the index into the CPU indirection table.
  716  * Each entry in the table contains the RSS CPU-ID returned by the NIC
  717  * create.  Based on the CPU ID, the receive completion is routed to
  718  * the corresponding RSS CQs.  (Non-RSS packets are always completed
  719  * on the default (0) CQ).
  720  *
  721  * @param sc            software handle to the device
  722  * @param *fwcmd        pointer to the rss mbox command
  723  * @returns             none
  724  */
  725 static int
  726 oce_rss_itbl_init(POCE_SOFTC sc, struct mbx_config_nic_rss *fwcmd)
  727 {
  728         int i = 0, j = 0, rc = 0;
  729         uint8_t *tbl = fwcmd->params.req.cputable;
  730         struct oce_rq *rq = NULL;
  731 
  732         for (j = 0; j < INDIRECTION_TABLE_ENTRIES ; j += (sc->nrqs - 1)) {
  733                 for_all_rss_queues(sc, rq, i) {
  734                         if ((j + i) >= INDIRECTION_TABLE_ENTRIES)
  735                                 break;
  736                         tbl[j + i] = rq->rss_cpuid;
  737                 }
  738         }
  739         if (i == 0) {
  740                 device_printf(sc->dev, "error: Invalid number of RSS RQ's\n");
  741                 rc = ENXIO;
  742 
  743         }
  744 
  745         /* fill log2 value indicating the size of the CPU table */
  746         if (rc == 0)
  747                 fwcmd->params.req.cpu_tbl_sz_log2 = LE_16(OCE_LOG2(i));
  748 
  749         return rc;
  750 }
  751 
  752 /**
  753  * @brief Function to set flow control capability in the hardware
  754  * @param sc            software handle to the device
  755  * @param if_id         interface id to read the address from
  756  * @param enable_rss    0=disable, RSS_ENABLE_xxx flags otherwise
  757  * @returns             0 on success, EIO on failure
  758  */
  759 int
  760 oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
  761 {
  762         int rc;
  763         struct oce_mbx mbx;
  764         struct mbx_config_nic_rss *fwcmd =
  765                                 (struct mbx_config_nic_rss *)&mbx.payload;
  766         int version;
  767 
  768         bzero(&mbx, sizeof(struct oce_mbx));
  769 
  770         if (IS_XE201(sc) || IS_SH(sc)) {
  771                 version = OCE_MBX_VER_V1;
  772                 fwcmd->params.req.enable_rss = RSS_ENABLE_UDP_IPV4 |
  773                                                RSS_ENABLE_UDP_IPV6;
  774         } else
  775                 version = OCE_MBX_VER_V0;
  776 
  777         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  778                                 MBX_SUBSYSTEM_NIC,
  779                                 NIC_CONFIG_RSS,
  780                                 MBX_TIMEOUT_SEC,
  781                                 sizeof(struct mbx_config_nic_rss),
  782                                 version);
  783         if (enable_rss)
  784                 fwcmd->params.req.enable_rss |= (RSS_ENABLE_IPV4 |
  785                                                  RSS_ENABLE_TCP_IPV4 |
  786                                                  RSS_ENABLE_IPV6 |
  787                                                  RSS_ENABLE_TCP_IPV6);
  788         fwcmd->params.req.flush = OCE_FLUSH;
  789         fwcmd->params.req.if_id = LE_32(if_id);
  790 
  791         skrandom(karc4random());        /* random entropy seed */
  792         read_random(fwcmd->params.req.hash, sizeof(fwcmd->params.req.hash));
  793 
  794         rc = oce_rss_itbl_init(sc, fwcmd);
  795         if (rc == 0) {
  796                 mbx.u0.s.embedded = 1;
  797                 mbx.payload_length = sizeof(struct mbx_config_nic_rss);
  798                 DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
  799 
  800                 rc = oce_mbox_post(sc, &mbx, NULL);
  801                 if (!rc)
  802                         rc = fwcmd->hdr.u0.rsp.status;
  803                 if (rc)
  804                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  805                               __FUNCTION__, rc);
  806         }
  807         return rc;
  808 }
  809 
  810 /**
  811  * @brief               RXF function to enable/disable device promiscuous mode
  812  * @param sc            software handle to the device
  813  * @param enable        enable/disable flag
  814  * @returns             0 on success, EIO on failure
  815  * @note
  816  *      The NIC_CONFIG_PROMISCUOUS command deprecated for Lancer.
  817  *      This function uses the COMMON_SET_IFACE_RX_FILTER command instead.
  818  */
  819 int
  820 oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable)
  821 {
  822         struct mbx_set_common_iface_rx_filter *fwcmd;
  823         int sz = sizeof(struct mbx_set_common_iface_rx_filter);
  824         iface_rx_filter_ctx_t *req;
  825         OCE_DMA_MEM sgl;
  826         int rc;
  827 
  828         /* allocate mbx payload's dma scatter/gather memory */
  829         rc = oce_dma_alloc(sc, sz, &sgl, 0);
  830         if (rc)
  831                 return rc;
  832 
  833         fwcmd = OCE_DMAPTR(&sgl, struct mbx_set_common_iface_rx_filter);
  834 
  835         req =  &fwcmd->params.req;
  836         req->iface_flags_mask = MBX_RX_IFACE_FLAGS_PROMISCUOUS |
  837                                 MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
  838         if (enable) {
  839                 req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS |
  840                                    MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
  841         }
  842         req->if_id = sc->if_id;
  843 
  844         rc = oce_set_common_iface_rx_filter(sc, &sgl);
  845         oce_dma_free(sc, &sgl);
  846 
  847         return rc;
  848 }
  849 
  850 
  851 /**
  852  * @brief                       Function modify and select rx filter options
  853  * @param sc                    software handle to the device
  854  * @param sgl                   scatter/gather request/response
  855  * @returns                     0 on success, error code on failure
  856  */
  857 int
  858 oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl)
  859 {
  860         struct oce_mbx mbx;
  861         int mbx_sz = sizeof(struct mbx_set_common_iface_rx_filter);
  862         struct mbx_set_common_iface_rx_filter *fwcmd;
  863         int rc;
  864 
  865         bzero(&mbx, sizeof(struct oce_mbx));
  866         fwcmd = OCE_DMAPTR(sgl, struct mbx_set_common_iface_rx_filter);
  867 
  868         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  869                                 MBX_SUBSYSTEM_COMMON,
  870                                 OPCODE_COMMON_SET_IFACE_RX_FILTER,
  871                                 MBX_TIMEOUT_SEC,
  872                                 mbx_sz,
  873                                 OCE_MBX_VER_V0);
  874 
  875         oce_dma_sync(sgl, BUS_DMASYNC_PREWRITE);
  876         mbx.u0.s.embedded = 0;
  877         mbx.u0.s.sge_count = 1;
  878         mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(sgl->paddr);
  879         mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(sgl->paddr);
  880         mbx.payload.u0.u1.sgl[0].length = mbx_sz;
  881         mbx.payload_length = mbx_sz;
  882         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
  883 
  884         rc = oce_mbox_post(sc, &mbx, NULL);
  885         if (!rc)
  886                 rc = fwcmd->hdr.u0.rsp.status;
  887         if (rc)
  888                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  889                               __FUNCTION__, rc);
  890         return 0;
  891 }
  892 
  893 /**
  894  * @brief Function to query the link status from the hardware
  895  * @param sc            software handle to the device
  896  * @param[out] link     pointer to the structure returning link attributes
  897  * @returns             0 on success, EIO on failure
  898  */
  899 int
  900 oce_get_link_status(POCE_SOFTC sc, struct link_status *link)
  901 {
  902         struct oce_mbx mbx;
  903         struct mbx_query_common_link_config *fwcmd;
  904         int rc = 0, version;
  905 
  906         bzero(&mbx, sizeof(struct oce_mbx));
  907 
  908         IS_XE201(sc) ? (version = OCE_MBX_VER_V1) : (version = OCE_MBX_VER_V0);
  909 
  910         fwcmd = (struct mbx_query_common_link_config *)&mbx.payload;
  911         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  912                                 MBX_SUBSYSTEM_COMMON,
  913                                 OPCODE_COMMON_QUERY_LINK_CONFIG,
  914                                 MBX_TIMEOUT_SEC,
  915                                 sizeof(struct mbx_query_common_link_config),
  916                                 version);
  917 
  918         mbx.u0.s.embedded = 1;
  919         mbx.payload_length = sizeof(struct mbx_query_common_link_config);
  920         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
  921 
  922         rc = oce_mbox_post(sc, &mbx, NULL);
  923 
  924         if (!rc)
  925                 rc = fwcmd->hdr.u0.rsp.status;
  926         if (rc) {
  927                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  928                               __FUNCTION__, rc);
  929                 goto error;
  930         }
  931         /* interpret response */
  932         bcopy(&fwcmd->params.rsp, link, sizeof(struct link_status));
  933         link->logical_link_status = LE_32(link->logical_link_status);
  934         link->qos_link_speed = LE_16(link->qos_link_speed);
  935 error:
  936         return rc;
  937 }
  938 
  939 
  940 
  941 int
  942 oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
  943 {
  944         struct oce_mbx mbx;
  945         struct mbx_get_nic_stats_v0 *fwcmd;
  946         int rc = 0;
  947 
  948         bzero(&mbx, sizeof(struct oce_mbx));
  949 
  950         fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats_v0);
  951         bzero(fwcmd, sizeof(struct mbx_get_nic_stats_v0));
  952 
  953         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
  954                                 MBX_SUBSYSTEM_NIC,
  955                                 NIC_GET_STATS,
  956                                 MBX_TIMEOUT_SEC,
  957                                 sizeof(struct mbx_get_nic_stats_v0),
  958                                 OCE_MBX_VER_V0);
  959 
  960         mbx.u0.s.embedded = 0;
  961         mbx.u0.s.sge_count = 1;
  962 
  963         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
  964 
  965         mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
  966         mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
  967         mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_nic_stats_v0);
  968 
  969         mbx.payload_length = sizeof(struct mbx_get_nic_stats_v0);
  970 
  971         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
  972 
  973         rc = oce_mbox_post(sc, &mbx, NULL);
  974 
  975         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
  976 
  977         if (!rc)
  978                 rc = fwcmd->hdr.u0.rsp.status;
  979         if (rc)
  980                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
  981                               __FUNCTION__, rc);
  982         return rc;
  983 }
  984 
  985 
  986 
  987 /**
  988  * @brief Function to get NIC statistics
  989  * @param sc            software handle to the device
  990  * @param *stats        pointer to where to store statistics
  991  * @param reset_stats   resets statistics of set
  992  * @returns             0 on success, EIO on failure
  993  * @note                command depricated in Lancer
  994  */
  995 int
  996 oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
  997 {
  998         struct oce_mbx mbx;
  999         struct mbx_get_nic_stats *fwcmd;
 1000         int rc = 0;
 1001 
 1002         bzero(&mbx, sizeof(struct oce_mbx));
 1003         fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_nic_stats);
 1004         bzero(fwcmd, sizeof(struct mbx_get_nic_stats));
 1005 
 1006         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1007                                 MBX_SUBSYSTEM_NIC,
 1008                                 NIC_GET_STATS,
 1009                                 MBX_TIMEOUT_SEC,
 1010                                 sizeof(struct mbx_get_nic_stats),
 1011                                 OCE_MBX_VER_V1);
 1012 
 1013 
 1014         mbx.u0.s.embedded = 0;  /* stats too large for embedded mbx rsp */
 1015         mbx.u0.s.sge_count = 1; /* using scatter gather instead */
 1016 
 1017         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
 1018         mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
 1019         mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
 1020         mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_nic_stats);
 1021 
 1022         mbx.payload_length = sizeof(struct mbx_get_nic_stats);
 1023         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1024 
 1025         rc = oce_mbox_post(sc, &mbx, NULL);
 1026         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
 1027         if (!rc)
 1028                 rc = fwcmd->hdr.u0.rsp.status;
 1029         if (rc)
 1030                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1031                               __FUNCTION__, rc);
 1032         return rc;
 1033 }
 1034 
 1035 
 1036 /**
 1037  * @brief Function to get pport (physical port) statistics
 1038  * @param sc            software handle to the device
 1039  * @param *stats        pointer to where to store statistics
 1040  * @param reset_stats   resets statistics of set
 1041  * @returns             0 on success, EIO on failure
 1042  */
 1043 int
 1044 oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
 1045                                 uint32_t reset_stats)
 1046 {
 1047         struct oce_mbx mbx;
 1048         struct mbx_get_pport_stats *fwcmd;
 1049         int rc = 0;
 1050 
 1051         bzero(&mbx, sizeof(struct oce_mbx));
 1052         fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_pport_stats);
 1053         bzero(fwcmd, sizeof(struct mbx_get_pport_stats));
 1054 
 1055         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1056                                 MBX_SUBSYSTEM_NIC,
 1057                                 NIC_GET_PPORT_STATS,
 1058                                 MBX_TIMEOUT_SEC,
 1059                                 sizeof(struct mbx_get_pport_stats),
 1060                                 OCE_MBX_VER_V0);
 1061 
 1062         fwcmd->params.req.reset_stats = reset_stats;
 1063         fwcmd->params.req.port_number = sc->port_id;
 1064 
 1065         mbx.u0.s.embedded = 0;  /* stats too large for embedded mbx rsp */
 1066         mbx.u0.s.sge_count = 1; /* using scatter gather instead */
 1067 
 1068         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
 1069         mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
 1070         mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
 1071         mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_pport_stats);
 1072 
 1073         mbx.payload_length = sizeof(struct mbx_get_pport_stats);
 1074         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1075 
 1076         rc = oce_mbox_post(sc, &mbx, NULL);
 1077         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
 1078 
 1079         if (!rc)
 1080                 rc = fwcmd->hdr.u0.rsp.status;
 1081         if (rc)
 1082                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1083                               __FUNCTION__, rc);
 1084         return rc;
 1085 }
 1086 
 1087 
 1088 /**
 1089  * @brief Function to get vport (virtual port) statistics
 1090  * @param sc            software handle to the device
 1091  * @param *stats        pointer to where to store statistics
 1092  * @param reset_stats   resets statistics of set
 1093  * @returns             0 on success, EIO on failure
 1094  */
 1095 int
 1096 oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
 1097                                 uint32_t req_size, uint32_t reset_stats)
 1098 {
 1099         struct oce_mbx mbx;
 1100         struct mbx_get_vport_stats *fwcmd;
 1101         int rc = 0;
 1102 
 1103         bzero(&mbx, sizeof(struct oce_mbx));
 1104 
 1105         fwcmd = OCE_DMAPTR(pstats_dma_mem, struct mbx_get_vport_stats);
 1106         bzero(fwcmd, sizeof(struct mbx_get_vport_stats));
 1107 
 1108         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1109                                 MBX_SUBSYSTEM_NIC,
 1110                                 NIC_GET_VPORT_STATS,
 1111                                 MBX_TIMEOUT_SEC,
 1112                                 sizeof(struct mbx_get_vport_stats),
 1113                                 OCE_MBX_VER_V0);
 1114 
 1115         fwcmd->params.req.reset_stats = reset_stats;
 1116         fwcmd->params.req.vport_number = sc->if_id;
 1117 
 1118         mbx.u0.s.embedded = 0;  /* stats too large for embedded mbx rsp */
 1119         mbx.u0.s.sge_count = 1; /* using scatter gather instead */
 1120 
 1121         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_PREWRITE);
 1122         mbx.payload.u0.u1.sgl[0].pa_lo = ADDR_LO(pstats_dma_mem->paddr);
 1123         mbx.payload.u0.u1.sgl[0].pa_hi = ADDR_HI(pstats_dma_mem->paddr);
 1124         mbx.payload.u0.u1.sgl[0].length = sizeof(struct mbx_get_vport_stats);
 1125 
 1126         mbx.payload_length = sizeof(struct mbx_get_vport_stats);
 1127         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1128 
 1129         rc = oce_mbox_post(sc, &mbx, NULL);
 1130         oce_dma_sync(pstats_dma_mem, BUS_DMASYNC_POSTWRITE);
 1131 
 1132         if (!rc)
 1133                 rc = fwcmd->hdr.u0.rsp.status;
 1134         if (rc)
 1135                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1136                               __FUNCTION__, rc);
 1137         return rc;
 1138 }
 1139 
 1140 
 1141 /**
 1142  * @brief               Function to update the muticast filter with
 1143  *                      values in dma_mem
 1144  * @param sc            software handle to the device
 1145  * @param dma_mem       pointer to dma memory region
 1146  * @returns             0 on success, EIO on failure
 1147  */
 1148 int
 1149 oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem)
 1150 {
 1151         struct oce_mbx mbx;
 1152         struct oce_mq_sge *sgl;
 1153         struct mbx_set_common_iface_multicast *req = NULL;
 1154         int rc = 0;
 1155 
 1156         req = OCE_DMAPTR(pdma_mem, struct mbx_set_common_iface_multicast);
 1157         mbx_common_req_hdr_init(&req->hdr, 0, 0,
 1158                                 MBX_SUBSYSTEM_COMMON,
 1159                                 OPCODE_COMMON_SET_IFACE_MULTICAST,
 1160                                 MBX_TIMEOUT_SEC,
 1161                                 sizeof(struct mbx_set_common_iface_multicast),
 1162                                 OCE_MBX_VER_V0);
 1163 
 1164         bzero(&mbx, sizeof(struct oce_mbx));
 1165 
 1166         mbx.u0.s.embedded = 0; /*Non embeded*/
 1167         mbx.payload_length = sizeof(struct mbx_set_common_iface_multicast);
 1168         mbx.u0.s.sge_count = 1;
 1169         sgl = &mbx.payload.u0.u1.sgl[0];
 1170         sgl->pa_hi = htole32(upper_32_bits(pdma_mem->paddr));
 1171         sgl->pa_lo = htole32((pdma_mem->paddr) & 0xFFFFFFFF);
 1172         sgl->length = htole32(mbx.payload_length);
 1173 
 1174         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1175 
 1176         rc = oce_mbox_post(sc, &mbx, NULL);
 1177         if (!rc)
 1178                 rc = req->hdr.u0.rsp.status;
 1179         if (rc)
 1180                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1181                               __FUNCTION__, rc);
 1182         return rc;
 1183 }
 1184 
 1185 
 1186 /**
 1187  * @brief               Function to send passthrough Ioctls
 1188  * @param sc            software handle to the device
 1189  * @param dma_mem       pointer to dma memory region
 1190  * @param req_size      size of dma_mem
 1191  * @returns             0 on success, EIO on failure
 1192  */
 1193 int
 1194 oce_pass_through_mbox(POCE_SOFTC sc, POCE_DMA_MEM dma_mem, uint32_t req_size)
 1195 {
 1196         struct oce_mbx mbx;
 1197         struct oce_mq_sge *sgl;
 1198         int rc = 0;
 1199 
 1200         bzero(&mbx, sizeof(struct oce_mbx));
 1201 
 1202         mbx.u0.s.embedded  = 0; /*Non embeded*/
 1203         mbx.payload_length = req_size;
 1204         mbx.u0.s.sge_count = 1;
 1205         sgl = &mbx.payload.u0.u1.sgl[0];
 1206         sgl->pa_hi = htole32(upper_32_bits(dma_mem->paddr));
 1207         sgl->pa_lo = htole32((dma_mem->paddr) & 0xFFFFFFFF);
 1208         sgl->length = htole32(req_size);
 1209 
 1210         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1211 
 1212         rc = oce_mbox_post(sc, &mbx, NULL);
 1213         return rc;
 1214 }
 1215 
 1216 
 1217 int
 1218 oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr,
 1219                  uint32_t if_id, uint32_t *pmac_id)
 1220 {
 1221         struct oce_mbx mbx;
 1222         struct mbx_add_common_iface_mac *fwcmd;
 1223         int rc = 0;
 1224 
 1225         bzero(&mbx, sizeof(struct oce_mbx));
 1226 
 1227         fwcmd = (struct mbx_add_common_iface_mac *)&mbx.payload;
 1228         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1229                                 MBX_SUBSYSTEM_COMMON,
 1230                                 OPCODE_COMMON_ADD_IFACE_MAC,
 1231                                 MBX_TIMEOUT_SEC,
 1232                                 sizeof(struct mbx_add_common_iface_mac),
 1233                                 OCE_MBX_VER_V0);
 1234 
 1235         fwcmd->params.req.if_id = (uint16_t) if_id;
 1236         bcopy(mac_addr, fwcmd->params.req.mac_address, 6);
 1237 
 1238         mbx.u0.s.embedded = 1;
 1239         mbx.payload_length = sizeof(struct  mbx_add_common_iface_mac);
 1240         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1241         rc = oce_mbox_post(sc, &mbx, NULL);
 1242         if (!rc)
 1243                 rc = fwcmd->hdr.u0.rsp.status;
 1244         if (rc) {
 1245                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1246                               __FUNCTION__, rc);
 1247                 goto error;
 1248         }
 1249         *pmac_id = fwcmd->params.rsp.pmac_id;
 1250 error:
 1251         return rc;
 1252 }
 1253 
 1254 
 1255 int
 1256 oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id)
 1257 {
 1258         struct oce_mbx mbx;
 1259         struct mbx_del_common_iface_mac *fwcmd;
 1260         int rc = 0;
 1261 
 1262         bzero(&mbx, sizeof(struct oce_mbx));
 1263 
 1264         fwcmd = (struct mbx_del_common_iface_mac *)&mbx.payload;
 1265         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1266                                 MBX_SUBSYSTEM_COMMON,
 1267                                 OPCODE_COMMON_DEL_IFACE_MAC,
 1268                                 MBX_TIMEOUT_SEC,
 1269                                 sizeof(struct mbx_del_common_iface_mac),
 1270                                 OCE_MBX_VER_V0);
 1271 
 1272         fwcmd->params.req.if_id = (uint16_t)if_id;
 1273         fwcmd->params.req.pmac_id = pmac_id;
 1274 
 1275         mbx.u0.s.embedded = 1;
 1276         mbx.payload_length = sizeof(struct  mbx_del_common_iface_mac);
 1277         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1278 
 1279         rc = oce_mbox_post(sc, &mbx, NULL);
 1280         if (!rc)
 1281                 rc = fwcmd->hdr.u0.rsp.status;
 1282         if (rc)
 1283                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1284                               __FUNCTION__, rc);
 1285         return rc;
 1286 }
 1287 
 1288 
 1289 
 1290 int
 1291 oce_mbox_check_native_mode(POCE_SOFTC sc)
 1292 {
 1293         struct oce_mbx mbx;
 1294         struct mbx_common_set_function_cap *fwcmd;
 1295         int rc = 0;
 1296 
 1297         bzero(&mbx, sizeof(struct oce_mbx));
 1298 
 1299         fwcmd = (struct mbx_common_set_function_cap *)&mbx.payload;
 1300         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1301                                 MBX_SUBSYSTEM_COMMON,
 1302                                 OPCODE_COMMON_SET_FUNCTIONAL_CAPS,
 1303                                 MBX_TIMEOUT_SEC,
 1304                                 sizeof(struct mbx_common_set_function_cap),
 1305                                 OCE_MBX_VER_V0);
 1306 
 1307         fwcmd->params.req.valid_capability_flags = CAP_SW_TIMESTAMPS |
 1308                                                         CAP_BE3_NATIVE_ERX_API;
 1309 
 1310         fwcmd->params.req.capability_flags = CAP_BE3_NATIVE_ERX_API;
 1311 
 1312         mbx.u0.s.embedded = 1;
 1313         mbx.payload_length = sizeof(struct mbx_common_set_function_cap);
 1314         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1315 
 1316         rc = oce_mbox_post(sc, &mbx, NULL);
 1317         if (!rc)
 1318                 rc = fwcmd->hdr.u0.rsp.status;
 1319         if (rc) {
 1320                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1321                               __FUNCTION__, rc);
 1322                 goto error;
 1323         }
 1324         sc->be3_native = fwcmd->params.rsp.capability_flags
 1325                         & CAP_BE3_NATIVE_ERX_API;
 1326 
 1327 error:
 1328         return 0;
 1329 }
 1330 
 1331 
 1332 
 1333 int
 1334 oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num,
 1335                 uint8_t loopback_type, uint8_t enable)
 1336 {
 1337         struct oce_mbx mbx;
 1338         struct mbx_lowlevel_set_loopback_mode *fwcmd;
 1339         int rc = 0;
 1340 
 1341 
 1342         bzero(&mbx, sizeof(struct oce_mbx));
 1343 
 1344         fwcmd = (struct mbx_lowlevel_set_loopback_mode *)&mbx.payload;
 1345         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1346                                 MBX_SUBSYSTEM_LOWLEVEL,
 1347                                 OPCODE_LOWLEVEL_SET_LOOPBACK_MODE,
 1348                                 MBX_TIMEOUT_SEC,
 1349                                 sizeof(struct mbx_lowlevel_set_loopback_mode),
 1350                                 OCE_MBX_VER_V0);
 1351 
 1352         fwcmd->params.req.src_port = port_num;
 1353         fwcmd->params.req.dest_port = port_num;
 1354         fwcmd->params.req.loopback_type = loopback_type;
 1355         fwcmd->params.req.loopback_state = enable;
 1356 
 1357         mbx.u0.s.embedded = 1;
 1358         mbx.payload_length = sizeof(struct  mbx_lowlevel_set_loopback_mode);
 1359         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1360 
 1361         rc = oce_mbox_post(sc, &mbx, NULL);
 1362         if (!rc)
 1363                 rc = fwcmd->hdr.u0.rsp.status;
 1364         if (rc)
 1365                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1366                               __FUNCTION__, rc);
 1367 
 1368         return rc;
 1369 
 1370 }
 1371 
 1372 int
 1373 oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
 1374         uint32_t loopback_type, uint32_t pkt_size, uint32_t num_pkts,
 1375         uint64_t pattern)
 1376 {
 1377 
 1378         struct oce_mbx mbx;
 1379         struct mbx_lowlevel_test_loopback_mode *fwcmd;
 1380         int rc = 0;
 1381 
 1382 
 1383         bzero(&mbx, sizeof(struct oce_mbx));
 1384 
 1385         fwcmd = (struct mbx_lowlevel_test_loopback_mode *)&mbx.payload;
 1386         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1387                                 MBX_SUBSYSTEM_LOWLEVEL,
 1388                                 OPCODE_LOWLEVEL_TEST_LOOPBACK,
 1389                                 MBX_TIMEOUT_SEC,
 1390                                 sizeof(struct mbx_lowlevel_test_loopback_mode),
 1391                                 OCE_MBX_VER_V0);
 1392 
 1393         fwcmd->params.req.pattern = pattern;
 1394         fwcmd->params.req.src_port = port_num;
 1395         fwcmd->params.req.dest_port = port_num;
 1396         fwcmd->params.req.pkt_size = pkt_size;
 1397         fwcmd->params.req.num_pkts = num_pkts;
 1398         fwcmd->params.req.loopback_type = loopback_type;
 1399 
 1400         mbx.u0.s.embedded = 1;
 1401         mbx.payload_length = sizeof(struct  mbx_lowlevel_test_loopback_mode);
 1402         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1403 
 1404         rc = oce_mbox_post(sc, &mbx, NULL);
 1405         if (!rc)
 1406                 rc = fwcmd->hdr.u0.rsp.status;
 1407         if (rc)
 1408                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1409                               __FUNCTION__, rc);
 1410 
 1411         return rc;
 1412 }
 1413 
 1414 int
 1415 oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
 1416                                 POCE_DMA_MEM pdma_mem, uint32_t num_bytes)
 1417 {
 1418 
 1419         struct oce_mbx mbx;
 1420         struct oce_mq_sge *sgl = NULL;
 1421         struct mbx_common_read_write_flashrom *fwcmd = NULL;
 1422         int rc = 0, payload_len = 0;
 1423 
 1424         bzero(&mbx, sizeof(struct oce_mbx));
 1425         fwcmd = OCE_DMAPTR(pdma_mem, struct mbx_common_read_write_flashrom);
 1426         payload_len = sizeof(struct mbx_common_read_write_flashrom) + 32*1024;
 1427 
 1428         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1429                                 MBX_SUBSYSTEM_COMMON,
 1430                                 OPCODE_COMMON_WRITE_FLASHROM,
 1431                                 LONG_TIMEOUT,
 1432                                 payload_len,
 1433                                 OCE_MBX_VER_V0);
 1434 
 1435         fwcmd->flash_op_type = optype;
 1436         fwcmd->flash_op_code = opcode;
 1437         fwcmd->data_buffer_size = num_bytes;
 1438 
 1439         mbx.u0.s.embedded  = 0; /*Non embeded*/
 1440         mbx.payload_length = payload_len;
 1441         mbx.u0.s.sge_count = 1;
 1442 
 1443         sgl = &mbx.payload.u0.u1.sgl[0];
 1444         sgl->pa_hi = upper_32_bits(pdma_mem->paddr);
 1445         sgl->pa_lo = pdma_mem->paddr & 0xFFFFFFFF;
 1446         sgl->length = payload_len;
 1447 
 1448         /* post the command */
 1449         rc = oce_mbox_post(sc, &mbx, NULL);
 1450         if (!rc)
 1451                 rc = fwcmd->hdr.u0.rsp.status;
 1452         if (rc)
 1453                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1454                               __FUNCTION__, rc);
 1455 
 1456         return rc;
 1457 
 1458 }
 1459 
 1460 int
 1461 oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc,
 1462                                 uint32_t offset, uint32_t optype)
 1463 {
 1464 
 1465         int rc = 0, payload_len = 0;
 1466         struct oce_mbx mbx;
 1467         struct mbx_common_read_write_flashrom *fwcmd;
 1468 
 1469         bzero(&mbx, sizeof(struct oce_mbx));
 1470 
 1471         fwcmd = (struct mbx_common_read_write_flashrom *)&mbx.payload;
 1472 
 1473         /* Firmware requires extra 4 bytes with this ioctl. Since there
 1474            is enough room in the mbx payload it should be good enough
 1475            Reference: Bug 14853
 1476         */
 1477         payload_len = sizeof(struct mbx_common_read_write_flashrom) + 4;
 1478 
 1479         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1480                                 MBX_SUBSYSTEM_COMMON,
 1481                                 OPCODE_COMMON_READ_FLASHROM,
 1482                                 MBX_TIMEOUT_SEC,
 1483                                 payload_len,
 1484                                 OCE_MBX_VER_V0);
 1485 
 1486         fwcmd->flash_op_type = optype;
 1487         fwcmd->flash_op_code = FLASHROM_OPER_REPORT;
 1488         fwcmd->data_offset = offset;
 1489         fwcmd->data_buffer_size = 0x4;
 1490 
 1491         mbx.u0.s.embedded  = 1;
 1492         mbx.payload_length = payload_len;
 1493 
 1494         /* post the command */
 1495         rc = oce_mbox_post(sc, &mbx, NULL);
 1496         if (!rc)
 1497                 rc = fwcmd->hdr.u0.rsp.status;
 1498         if (rc) {
 1499                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1500                               __FUNCTION__, rc);
 1501                 goto error;
 1502         }
 1503         bcopy(fwcmd->data_buffer, flash_crc, 4);
 1504 error:
 1505         return rc;
 1506 }
 1507 
 1508 int
 1509 oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info)
 1510 {
 1511 
 1512         struct oce_mbx mbx;
 1513         struct mbx_common_phy_info *fwcmd;
 1514         int rc = 0;
 1515 
 1516         bzero(&mbx, sizeof(struct oce_mbx));
 1517 
 1518         fwcmd = (struct mbx_common_phy_info *)&mbx.payload;
 1519         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1520                                 MBX_SUBSYSTEM_COMMON,
 1521                                 OPCODE_COMMON_GET_PHY_CONFIG,
 1522                                 MBX_TIMEOUT_SEC,
 1523                                 sizeof(struct mbx_common_phy_info),
 1524                                 OCE_MBX_VER_V0);
 1525 
 1526         mbx.u0.s.embedded = 1;
 1527         mbx.payload_length = sizeof(struct  mbx_common_phy_info);
 1528 
 1529         /* now post the command */
 1530         rc = oce_mbox_post(sc, &mbx, NULL);
 1531         if (!rc)
 1532                 rc = fwcmd->hdr.u0.rsp.status;
 1533         if (rc) {
 1534                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1535                               __FUNCTION__, rc);
 1536                 goto error;
 1537         }
 1538         phy_info->phy_type = fwcmd->params.rsp.phy_info.phy_type;
 1539         phy_info->interface_type =
 1540                         fwcmd->params.rsp.phy_info.interface_type;
 1541         phy_info->auto_speeds_supported =
 1542                 fwcmd->params.rsp.phy_info.auto_speeds_supported;
 1543         phy_info->fixed_speeds_supported =
 1544                 fwcmd->params.rsp.phy_info.fixed_speeds_supported;
 1545         phy_info->misc_params =fwcmd->params.rsp.phy_info.misc_params;
 1546 error:
 1547         return rc;
 1548 
 1549 }
 1550 
 1551 
 1552 int
 1553 oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size,
 1554                         uint32_t data_offset, POCE_DMA_MEM pdma_mem,
 1555                         uint32_t *written_data, uint32_t *additional_status)
 1556 {
 1557 
 1558         struct oce_mbx mbx;
 1559         struct mbx_lancer_common_write_object *fwcmd = NULL;
 1560         int rc = 0, payload_len = 0;
 1561 
 1562         bzero(&mbx, sizeof(struct oce_mbx));
 1563         payload_len = sizeof(struct mbx_lancer_common_write_object);
 1564 
 1565         mbx.u0.s.embedded  = 1;/* Embedded */
 1566         mbx.payload_length = payload_len;
 1567         fwcmd = (struct mbx_lancer_common_write_object *)&mbx.payload;
 1568 
 1569         /* initialize the ioctl header */
 1570         mbx_common_req_hdr_init(&fwcmd->params.req.hdr, 0, 0,
 1571                                 MBX_SUBSYSTEM_COMMON,
 1572                                 OPCODE_COMMON_WRITE_OBJECT,
 1573                                 LONG_TIMEOUT,
 1574                                 payload_len,
 1575                                 OCE_MBX_VER_V0);
 1576 
 1577         fwcmd->params.req.write_length = data_size;
 1578         if (data_size == 0)
 1579                 fwcmd->params.req.eof = 1;
 1580         else
 1581                 fwcmd->params.req.eof = 0;
 1582 
 1583         strcpy(fwcmd->params.req.object_name, "/prg");
 1584         fwcmd->params.req.descriptor_count = 1;
 1585         fwcmd->params.req.write_offset = data_offset;
 1586         fwcmd->params.req.buffer_length = data_size;
 1587         fwcmd->params.req.address_lower = pdma_mem->paddr & 0xFFFFFFFF;
 1588         fwcmd->params.req.address_upper = upper_32_bits(pdma_mem->paddr);
 1589 
 1590         /* post the command */
 1591         rc = oce_mbox_post(sc, &mbx, NULL);
 1592         if (!rc)
 1593                 rc = fwcmd->params.rsp.status;
 1594         if (rc) {
 1595                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1596                               __FUNCTION__, rc);
 1597                 goto error;
 1598         }
 1599         *written_data = fwcmd->params.rsp.actual_write_length;
 1600         *additional_status = fwcmd->params.rsp.additional_status;
 1601 error:
 1602         return rc;
 1603 
 1604 }
 1605 
 1606 
 1607 
 1608 int
 1609 oce_mbox_create_rq(struct oce_rq *rq)
 1610 {
 1611 
 1612         struct oce_mbx mbx;
 1613         struct mbx_create_nic_rq *fwcmd;
 1614         POCE_SOFTC sc = rq->parent;
 1615         int rc, num_pages = 0;
 1616 
 1617         if (rq->qstate == QCREATED)
 1618                 return 0;
 1619 
 1620         bzero(&mbx, sizeof(struct oce_mbx));
 1621 
 1622         fwcmd = (struct mbx_create_nic_rq *)&mbx.payload;
 1623         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1624                                 MBX_SUBSYSTEM_NIC,
 1625                                 NIC_CREATE_RQ, MBX_TIMEOUT_SEC,
 1626                                 sizeof(struct mbx_create_nic_rq),
 1627                                 OCE_MBX_VER_V0);
 1628 
 1629         /* oce_page_list will also prepare pages */
 1630         num_pages = oce_page_list(rq->ring, &fwcmd->params.req.pages[0]);
 1631 
 1632         if (IS_XE201(sc)) {
 1633                 fwcmd->params.req.frag_size = rq->cfg.frag_size/2048;
 1634                 fwcmd->params.req.page_size = 1;
 1635                 fwcmd->hdr.u0.req.version = OCE_MBX_VER_V1;
 1636         } else
 1637                 fwcmd->params.req.frag_size = OCE_LOG2(rq->cfg.frag_size);
 1638         fwcmd->params.req.num_pages = num_pages;
 1639         fwcmd->params.req.cq_id = rq->cq->cq_id;
 1640         fwcmd->params.req.if_id = sc->if_id;
 1641         fwcmd->params.req.max_frame_size = rq->cfg.mtu;
 1642         fwcmd->params.req.is_rss_queue = rq->cfg.is_rss_queue;
 1643 
 1644         mbx.u0.s.embedded = 1;
 1645         mbx.payload_length = sizeof(struct mbx_create_nic_rq);
 1646 
 1647         rc = oce_mbox_post(sc, &mbx, NULL);
 1648         if (!rc)
 1649                 rc = fwcmd->hdr.u0.rsp.status;
 1650         if (rc) {
 1651                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1652                               __FUNCTION__, rc);
 1653                 goto error;
 1654         }
 1655         rq->rq_id = fwcmd->params.rsp.rq_id;
 1656         rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid;
 1657 error:
 1658         return rc;
 1659 
 1660 }
 1661 
 1662 
 1663 
 1664 int
 1665 oce_mbox_create_wq(struct oce_wq *wq)
 1666 {
 1667         struct oce_mbx mbx;
 1668         struct mbx_create_nic_wq *fwcmd;
 1669         POCE_SOFTC sc = wq->parent;
 1670         int rc = 0, version, num_pages;
 1671 
 1672         bzero(&mbx, sizeof(struct oce_mbx));
 1673 
 1674         fwcmd = (struct mbx_create_nic_wq *)&mbx.payload;
 1675         if (IS_XE201(sc)) {
 1676                 version = OCE_MBX_VER_V1;
 1677                 fwcmd->params.req.if_id = sc->if_id;
 1678         } else if (IS_BE(sc))
 1679                 IS_PROFILE_SUPER_NIC(sc) ? (version = OCE_MBX_VER_V2)
 1680                                          : (version = OCE_MBX_VER_V0);
 1681         else
 1682                 version = OCE_MBX_VER_V2;
 1683 
 1684         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1685                                 MBX_SUBSYSTEM_NIC,
 1686                                 NIC_CREATE_WQ, MBX_TIMEOUT_SEC,
 1687                                 sizeof(struct mbx_create_nic_wq),
 1688                                 version);
 1689 
 1690         num_pages = oce_page_list(wq->ring, &fwcmd->params.req.pages[0]);
 1691 
 1692         fwcmd->params.req.nic_wq_type = wq->cfg.wq_type;
 1693         fwcmd->params.req.num_pages = num_pages;
 1694         fwcmd->params.req.wq_size = OCE_LOG2(wq->cfg.q_len) + 1;
 1695         fwcmd->params.req.cq_id = wq->cq->cq_id;
 1696         fwcmd->params.req.ulp_num = 1;
 1697 
 1698         mbx.u0.s.embedded = 1;
 1699         mbx.payload_length = sizeof(struct mbx_create_nic_wq);
 1700 
 1701         rc = oce_mbox_post(sc, &mbx, NULL);
 1702         if (!rc)
 1703                 rc = fwcmd->hdr.u0.rsp.status;
 1704         if (rc) {
 1705                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1706                               __FUNCTION__, rc);
 1707                 goto error;
 1708         }
 1709         wq->wq_id = LE_16(fwcmd->params.rsp.wq_id);
 1710         if (version == OCE_MBX_VER_V2)
 1711                 wq->db_offset = LE_32(fwcmd->params.rsp.db_offset);
 1712         else
 1713                 wq->db_offset = PD_TXULP_DB;
 1714 error:
 1715         return rc;
 1716 
 1717 }
 1718 
 1719 
 1720 
 1721 int
 1722 oce_mbox_create_eq(struct oce_eq *eq)
 1723 {
 1724         struct oce_mbx mbx;
 1725         struct mbx_create_common_eq *fwcmd;
 1726         POCE_SOFTC sc = eq->parent;
 1727         int rc = 0;
 1728         uint32_t num_pages;
 1729 
 1730         bzero(&mbx, sizeof(struct oce_mbx));
 1731 
 1732         fwcmd = (struct mbx_create_common_eq *)&mbx.payload;
 1733 
 1734         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1735                                 MBX_SUBSYSTEM_COMMON,
 1736                                 OPCODE_COMMON_CREATE_EQ, MBX_TIMEOUT_SEC,
 1737                                 sizeof(struct mbx_create_common_eq),
 1738                                 OCE_MBX_VER_V0);
 1739 
 1740         num_pages = oce_page_list(eq->ring, &fwcmd->params.req.pages[0]);
 1741         fwcmd->params.req.ctx.num_pages = num_pages;
 1742         fwcmd->params.req.ctx.valid = 1;
 1743         fwcmd->params.req.ctx.size = (eq->eq_cfg.item_size == 4) ? 0 : 1;
 1744         fwcmd->params.req.ctx.count = OCE_LOG2(eq->eq_cfg.q_len / 256);
 1745         fwcmd->params.req.ctx.armed = 0;
 1746         fwcmd->params.req.ctx.delay_mult = eq->eq_cfg.cur_eqd;
 1747 
 1748 
 1749         mbx.u0.s.embedded = 1;
 1750         mbx.payload_length = sizeof(struct mbx_create_common_eq);
 1751 
 1752         rc = oce_mbox_post(sc, &mbx, NULL);
 1753         if (!rc)
 1754                 rc = fwcmd->hdr.u0.rsp.status;
 1755         if (rc) {
 1756                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1757                               __FUNCTION__, rc);
 1758                 goto error;
 1759         }
 1760         eq->eq_id = LE_16(fwcmd->params.rsp.eq_id);
 1761 error:
 1762         return rc;
 1763 }
 1764 
 1765 
 1766 
 1767 int
 1768 oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce, uint32_t is_eventable)
 1769 {
 1770         struct oce_mbx mbx;
 1771         struct mbx_create_common_cq *fwcmd;
 1772         POCE_SOFTC sc = cq->parent;
 1773         uint8_t version;
 1774         oce_cq_ctx_t *ctx;
 1775         uint32_t num_pages, page_size;
 1776         int rc = 0;
 1777 
 1778 
 1779         bzero(&mbx, sizeof(struct oce_mbx));
 1780 
 1781         fwcmd = (struct mbx_create_common_cq *)&mbx.payload;
 1782 
 1783         if (IS_XE201(sc))
 1784                 version = OCE_MBX_VER_V2;
 1785         else
 1786                 version = OCE_MBX_VER_V0;
 1787 
 1788         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1789                                 MBX_SUBSYSTEM_COMMON,
 1790                                 OPCODE_COMMON_CREATE_CQ,
 1791                                 MBX_TIMEOUT_SEC,
 1792                                 sizeof(struct mbx_create_common_cq),
 1793                                 version);
 1794 
 1795         ctx = &fwcmd->params.req.cq_ctx;
 1796 
 1797         num_pages = oce_page_list(cq->ring, &fwcmd->params.req.pages[0]);
 1798         page_size =  1;  /* 1 for 4K */
 1799 
 1800         if (version == OCE_MBX_VER_V2) {
 1801                 ctx->v2.num_pages = LE_16(num_pages);
 1802                 ctx->v2.page_size = page_size;
 1803                 ctx->v2.eventable = is_eventable;
 1804                 ctx->v2.valid = 1;
 1805                 ctx->v2.count = OCE_LOG2(cq->cq_cfg.q_len / 256);
 1806                 ctx->v2.nodelay = cq->cq_cfg.nodelay;
 1807                 ctx->v2.coalesce_wm = ncoalesce;
 1808                 ctx->v2.armed = 0;
 1809                 ctx->v2.eq_id = cq->eq->eq_id;
 1810                 if (ctx->v2.count == 3) {
 1811                         if (cq->cq_cfg.q_len > (4*1024)-1)
 1812                                 ctx->v2.cqe_count = (4*1024)-1;
 1813                         else
 1814                                 ctx->v2.cqe_count = cq->cq_cfg.q_len;
 1815                 }
 1816         } else {
 1817                 ctx->v0.num_pages = LE_16(num_pages);
 1818                 ctx->v0.eventable = is_eventable;
 1819                 ctx->v0.valid = 1;
 1820                 ctx->v0.count = OCE_LOG2(cq->cq_cfg.q_len / 256);
 1821                 ctx->v0.nodelay = cq->cq_cfg.nodelay;
 1822                 ctx->v0.coalesce_wm = ncoalesce;
 1823                 ctx->v0.armed = 0;
 1824                 ctx->v0.eq_id = cq->eq->eq_id;
 1825         }
 1826 
 1827         mbx.u0.s.embedded = 1;
 1828         mbx.payload_length = sizeof(struct mbx_create_common_cq);
 1829 
 1830         rc = oce_mbox_post(sc, &mbx, NULL);
 1831         if (!rc)
 1832                 rc = fwcmd->hdr.u0.rsp.status;
 1833         if (rc) {
 1834                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1835                               __FUNCTION__, rc);
 1836                 goto error;
 1837         }
 1838         cq->cq_id = LE_16(fwcmd->params.rsp.cq_id);
 1839 error:
 1840         return rc;
 1841 
 1842 }
 1843 
 1844 int
 1845 oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
 1846 {
 1847         int rc = 0;
 1848         struct oce_mbx mbx;
 1849         struct mbx_read_common_transrecv_data *fwcmd;
 1850         struct oce_mq_sge *sgl;
 1851         OCE_DMA_MEM dma;
 1852 
 1853         /* Allocate DMA mem*/
 1854         if (oce_dma_alloc(sc, sizeof(struct mbx_read_common_transrecv_data),
 1855                                 &dma, 0))
 1856                 return ENOMEM;
 1857 
 1858         fwcmd = OCE_DMAPTR(&dma, struct mbx_read_common_transrecv_data);
 1859         bzero(fwcmd, sizeof(struct mbx_read_common_transrecv_data));
 1860 
 1861         bzero(&mbx, sizeof(struct oce_mbx));
 1862         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1863                         MBX_SUBSYSTEM_COMMON,
 1864                         OPCODE_COMMON_READ_TRANSRECEIVER_DATA,
 1865                         MBX_TIMEOUT_SEC,
 1866                         sizeof(struct mbx_read_common_transrecv_data),
 1867                         OCE_MBX_VER_V0);
 1868 
 1869         /* fill rest of mbx */
 1870         mbx.u0.s.embedded = 0;
 1871         mbx.payload_length = sizeof(struct mbx_read_common_transrecv_data);
 1872         mbx.u0.s.sge_count = 1;
 1873         sgl = &mbx.payload.u0.u1.sgl[0];
 1874         sgl->pa_hi = htole32(upper_32_bits(dma.paddr));
 1875         sgl->pa_lo = htole32((dma.paddr) & 0xFFFFFFFF);
 1876         sgl->length = htole32(mbx.payload_length);
 1877         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1878 
 1879         fwcmd->params.req.port = LE_32(sc->port_id);
 1880         fwcmd->params.req.page_num = LE_32(page_num);
 1881 
 1882         /* command post */
 1883         rc = oce_mbox_post(sc, &mbx, NULL);
 1884         if (!rc)
 1885                 rc = fwcmd->hdr.u0.rsp.status;
 1886         if (rc) {
 1887                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1888                               __FUNCTION__, rc);
 1889                 goto error;
 1890         }
 1891         if(fwcmd->params.rsp.page_num == PAGE_NUM_A0)
 1892         {
 1893                 bcopy((char *)fwcmd->params.rsp.page_data,
 1894                                 (char *)&sfp_vpd_dump_buffer[0],
 1895                                 TRANSCEIVER_A0_SIZE);
 1896         }
 1897 
 1898         if(fwcmd->params.rsp.page_num == PAGE_NUM_A2)
 1899         {
 1900                 bcopy((char *)fwcmd->params.rsp.page_data,
 1901                                 (char *)&sfp_vpd_dump_buffer[32],
 1902                                 TRANSCEIVER_A2_SIZE);
 1903         }
 1904 error:
 1905         oce_dma_free(sc, &dma);
 1906         return rc;
 1907 }
 1908 
 1909 void
 1910 oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
 1911                                 int num)
 1912 {
 1913         struct oce_mbx mbx;
 1914         struct mbx_modify_common_eq_delay *fwcmd;
 1915         int rc = 0;
 1916         int i = 0;
 1917 
 1918         bzero(&mbx, sizeof(struct oce_mbx));
 1919 
 1920         /* Initialize MODIFY_EQ_DELAY ioctl header */
 1921         fwcmd = (struct mbx_modify_common_eq_delay *)&mbx.payload;
 1922         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1923                                 MBX_SUBSYSTEM_COMMON,
 1924                                 OPCODE_COMMON_MODIFY_EQ_DELAY,
 1925                                 MBX_TIMEOUT_SEC,
 1926                                 sizeof(struct mbx_modify_common_eq_delay),
 1927                                 OCE_MBX_VER_V0);
 1928         /* fill rest of mbx */
 1929         mbx.u0.s.embedded = 1;
 1930         mbx.payload_length = sizeof(struct mbx_modify_common_eq_delay);
 1931         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 1932 
 1933         fwcmd->params.req.num_eq = num;
 1934         for (i = 0; i < num; i++) {
 1935                 fwcmd->params.req.delay[i].eq_id =
 1936                                         htole32(set_eqd[i].eq_id);
 1937                 fwcmd->params.req.delay[i].phase = 0;
 1938                 fwcmd->params.req.delay[i].dm =
 1939                 htole32(set_eqd[i].delay_multiplier);
 1940         }
 1941 
 1942 
 1943         /* command post */
 1944         rc = oce_mbox_post(sc, &mbx, NULL);
 1945 
 1946         if (!rc)
 1947                 rc = fwcmd->hdr.u0.rsp.status;
 1948         if (rc)
 1949                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 1950                               __FUNCTION__, rc);
 1951 }
 1952 
 1953 int
 1954 oce_get_profile_config(POCE_SOFTC sc)
 1955 {
 1956         struct oce_mbx mbx;
 1957         struct mbx_common_get_profile_config *fwcmd;
 1958         int rc = 0;
 1959         int version = 0;
 1960         struct oce_mq_sge *sgl;
 1961         OCE_DMA_MEM dma;
 1962         uint32_t desc_count = 0;
 1963         struct oce_nic_resc_desc *nic_desc = NULL;
 1964         int i;
 1965         boolean_t nic_desc_valid = FALSE;
 1966 
 1967         if (IS_BE2(sc))
 1968                 return -1;
 1969 
 1970         /* Allocate DMA mem*/
 1971         if (oce_dma_alloc(sc, sizeof(struct mbx_common_get_profile_config),
 1972                           &dma, 0))
 1973                 return ENOMEM;
 1974 
 1975         /* Initialize MODIFY_EQ_DELAY ioctl header */
 1976         fwcmd = OCE_DMAPTR(&dma, struct mbx_common_get_profile_config);
 1977         bzero(fwcmd, sizeof(struct mbx_common_get_profile_config));
 1978 
 1979         if (IS_BE3(sc))
 1980                 version = OCE_MBX_VER_V1;
 1981         else
 1982                 version = OCE_MBX_VER_V0;
 1983 
 1984         bzero(&mbx, sizeof(struct oce_mbx));
 1985         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 1986                                 MBX_SUBSYSTEM_COMMON,
 1987                                 OPCODE_COMMON_GET_PROFILE_CONFIG,
 1988                                 MBX_TIMEOUT_SEC,
 1989                                 sizeof(struct mbx_common_get_profile_config),
 1990                                 version);
 1991         /* fill rest of mbx */
 1992         mbx.u0.s.embedded = 0;
 1993         mbx.payload_length = sizeof(struct mbx_common_get_profile_config);
 1994         mbx.u0.s.sge_count = 1;
 1995         sgl = &mbx.payload.u0.u1.sgl[0];
 1996         sgl->pa_hi = htole32(upper_32_bits(dma.paddr));
 1997         sgl->pa_lo = htole32((dma.paddr) & 0xFFFFFFFF);
 1998         sgl->length = htole32(mbx.payload_length);
 1999         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 2000 
 2001         fwcmd->params.req.type = ACTIVE_PROFILE;
 2002 
 2003         /* command post */
 2004         rc = oce_mbox_post(sc, &mbx, NULL);
 2005         if (!rc)
 2006                 rc = fwcmd->hdr.u0.rsp.status;
 2007         if (rc) {
 2008                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 2009                               __FUNCTION__, rc);
 2010                 goto error;
 2011         }
 2012 
 2013         nic_desc = (struct oce_nic_resc_desc *) fwcmd->params.rsp.resources;
 2014         desc_count = HOST_32(fwcmd->params.rsp.desc_count);
 2015         for (i = 0; i < desc_count; i++) {
 2016                 if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
 2017                     (nic_desc->desc_type == NIC_RESC_DESC_TYPE_V1)) {
 2018                         nic_desc_valid = TRUE;
 2019                         break;
 2020                 }
 2021                 nic_desc = (struct oce_nic_resc_desc *) \
 2022                                 ((char *)nic_desc + nic_desc->desc_len);
 2023         }
 2024         if (!nic_desc_valid) {
 2025                 rc = -1;
 2026                 goto error;
 2027         }
 2028         else {
 2029                 sc->nwqs = HOST_32(nic_desc->txq_count);
 2030                 if (sc->nwqs)
 2031                         sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);
 2032                 else
 2033                         sc->nwqs = OCE_MAX_WQ;
 2034 
 2035         }
 2036 error:
 2037         oce_dma_free(sc, &dma);
 2038         return rc;
 2039 
 2040 }
 2041 
 2042 int
 2043 oce_get_func_config(POCE_SOFTC sc)
 2044 {
 2045         struct oce_mbx mbx;
 2046         struct mbx_common_get_func_config *fwcmd;
 2047         int rc = 0;
 2048         int version = 0;
 2049         struct oce_mq_sge *sgl;
 2050         OCE_DMA_MEM dma;
 2051         uint32_t desc_count = 0;
 2052         struct oce_nic_resc_desc *nic_desc = NULL;
 2053         int i;
 2054         boolean_t nic_desc_valid = FALSE;
 2055         uint32_t max_rss = 0;
 2056 
 2057         if ((IS_BE(sc) || IS_SH(sc)) && (!sc->be3_native))
 2058                 max_rss = OCE_LEGACY_MODE_RSS;
 2059         else
 2060                 max_rss = OCE_MAX_RSS;
 2061 
 2062         /* Allocate DMA mem*/
 2063         if (oce_dma_alloc(sc, sizeof(struct mbx_common_get_func_config),
 2064                           &dma, 0))
 2065                 return ENOMEM;
 2066 
 2067         /* Initialize MODIFY_EQ_DELAY ioctl header */
 2068         fwcmd = OCE_DMAPTR(&dma, struct mbx_common_get_func_config);
 2069         bzero(fwcmd, sizeof(struct mbx_common_get_func_config));
 2070 
 2071         if (IS_SH(sc))
 2072                 version = OCE_MBX_VER_V1;
 2073         else
 2074                 version = OCE_MBX_VER_V0;
 2075 
 2076         bzero(&mbx, sizeof(struct oce_mbx));
 2077         mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
 2078                                 MBX_SUBSYSTEM_COMMON,
 2079                                 OPCODE_COMMON_GET_FUNCTION_CONFIG,
 2080                                 MBX_TIMEOUT_SEC,
 2081                                 sizeof(struct mbx_common_get_func_config),
 2082                                 version);
 2083         /* fill rest of mbx */
 2084         mbx.u0.s.embedded = 0;
 2085         mbx.payload_length = sizeof(struct mbx_common_get_func_config);
 2086         mbx.u0.s.sge_count = 1;
 2087         sgl = &mbx.payload.u0.u1.sgl[0];
 2088         sgl->pa_hi = htole32(upper_32_bits(dma.paddr));
 2089         sgl->pa_lo = htole32((dma.paddr) & 0xFFFFFFFF);
 2090         sgl->length = htole32(mbx.payload_length);
 2091         DW_SWAP(u32ptr(&mbx), mbx.payload_length + OCE_BMBX_RHDR_SZ);
 2092 
 2093         /* command post */
 2094         rc = oce_mbox_post(sc, &mbx, NULL);
 2095         if (!rc)
 2096                 rc = fwcmd->hdr.u0.rsp.status;
 2097         if (rc) {
 2098                 device_printf(sc->dev,"%s failed - cmd status: %d\n",
 2099                               __FUNCTION__, rc);
 2100                 goto error;
 2101         }
 2102 
 2103         nic_desc = (struct oce_nic_resc_desc *) fwcmd->params.rsp.resources;
 2104         desc_count = HOST_32(fwcmd->params.rsp.desc_count);
 2105         for (i = 0; i < desc_count; i++) {
 2106                 if ((nic_desc->desc_type == NIC_RESC_DESC_TYPE_V0) ||
 2107                     (nic_desc->desc_type == NIC_RESC_DESC_TYPE_V1)) {
 2108                         nic_desc_valid = TRUE;
 2109                         break;
 2110                 }
 2111                 nic_desc = (struct oce_nic_resc_desc *) \
 2112                                 ((char *)nic_desc + nic_desc->desc_len);
 2113         }
 2114         if (!nic_desc_valid) {
 2115                 rc = -1;
 2116                 goto error;
 2117         }
 2118         else {
 2119                 sc->nwqs = HOST_32(nic_desc->txq_count);
 2120                 if (sc->nwqs)
 2121                         sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);
 2122                 else
 2123                         sc->nwqs = OCE_MAX_WQ;
 2124 
 2125                 sc->nrssqs = HOST_32(nic_desc->rssq_count);
 2126                 if (sc->nrssqs)
 2127                         sc->nrssqs = MIN(sc->nrssqs, max_rss);
 2128                 else
 2129                         sc->nrssqs = max_rss;
 2130                 sc->nrqs =  sc->nrssqs + 1; /* 1 for def RX */;
 2131         }
 2132 error:
 2133         oce_dma_free(sc, &dma);
 2134         return rc;
 2135 
 2136 }

Cache object: ccef8d4de7167f367fba8964112d5ad7


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