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

Cache object: 39dec10b2246c3cb9545024fbec04485


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