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/bnxt/bnxt_hwrm.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  * Broadcom NetXtreme-C/E network driver.
    3  *
    4  * Copyright (c) 2016 Broadcom, All Rights Reserved.
    5  * The term Broadcom refers to Broadcom Limited and/or its subsidiaries
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
   17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
   20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   26  * THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/endian.h>
   33 
   34 #include "bnxt.h"
   35 #include "bnxt_hwrm.h"
   36 #include "hsi_struct_def.h"
   37 
   38 static int bnxt_hwrm_err_map(uint16_t err);
   39 static inline int _is_valid_ether_addr(uint8_t *);
   40 static inline void get_random_ether_addr(uint8_t *);
   41 static void     bnxt_hwrm_set_link_common(struct bnxt_softc *softc,
   42                     struct hwrm_port_phy_cfg_input *req);
   43 static void     bnxt_hwrm_set_pause_common(struct bnxt_softc *softc,
   44                     struct hwrm_port_phy_cfg_input *req);
   45 static void     bnxt_hwrm_set_eee(struct bnxt_softc *softc,
   46                     struct hwrm_port_phy_cfg_input *req);
   47 static int      _hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
   48 static int      hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
   49 static void bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *, void *, uint16_t);
   50 
   51 /* NVRam stuff has a five minute timeout */
   52 #define BNXT_NVM_TIMEO  (5 * 60 * 1000)
   53 
   54 static int
   55 bnxt_hwrm_err_map(uint16_t err)
   56 {
   57         int rc;
   58 
   59         switch (err) {
   60         case HWRM_ERR_CODE_SUCCESS:
   61                 return 0;
   62         case HWRM_ERR_CODE_INVALID_PARAMS:
   63         case HWRM_ERR_CODE_INVALID_FLAGS:
   64         case HWRM_ERR_CODE_INVALID_ENABLES:
   65                 return EINVAL;
   66         case HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED:
   67                 return EACCES;
   68         case HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR:
   69                 return ENOMEM;
   70         case HWRM_ERR_CODE_CMD_NOT_SUPPORTED:
   71                 return ENOSYS;
   72         case HWRM_ERR_CODE_FAIL:
   73                 return EIO;
   74         case HWRM_ERR_CODE_HWRM_ERROR:
   75         case HWRM_ERR_CODE_UNKNOWN_ERR:
   76         default:
   77                 return EDOOFUS;
   78         }
   79 
   80         return rc;
   81 }
   82 
   83 int
   84 bnxt_alloc_hwrm_dma_mem(struct bnxt_softc *softc)
   85 {
   86         int rc;
   87 
   88         rc = iflib_dma_alloc(softc->ctx, PAGE_SIZE, &softc->hwrm_cmd_resp,
   89             BUS_DMA_NOWAIT);
   90         return rc;
   91 }
   92 
   93 void
   94 bnxt_free_hwrm_dma_mem(struct bnxt_softc *softc)
   95 {
   96         if (softc->hwrm_cmd_resp.idi_vaddr)
   97                 iflib_dma_free(&softc->hwrm_cmd_resp);
   98         softc->hwrm_cmd_resp.idi_vaddr = NULL;
   99         return;
  100 }
  101 
  102 static void
  103 bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *softc, void *request,
  104     uint16_t req_type)
  105 {
  106         struct input *req = request;
  107 
  108         req->req_type = htole16(req_type);
  109         req->cmpl_ring = 0xffff;
  110         req->target_id = 0xffff;
  111         req->resp_addr = htole64(softc->hwrm_cmd_resp.idi_paddr);
  112 }
  113 
  114 static int
  115 _hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
  116 {
  117         struct input *req = msg;
  118         struct hwrm_err_output *resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
  119         uint32_t *data = msg;
  120         int i;
  121         uint8_t *valid;
  122         uint16_t err;
  123         uint16_t max_req_len = BNXT_HWRM_MAX_REQ_LEN;
  124         struct hwrm_short_input short_input = {0};
  125 
  126         /* TODO: DMASYNC in here. */
  127         req->seq_id = htole16(softc->hwrm_cmd_seq++);
  128         memset(resp, 0, PAGE_SIZE);
  129 
  130         if ((softc->flags & BNXT_FLAG_SHORT_CMD) ||
  131             msg_len > BNXT_HWRM_MAX_REQ_LEN) {
  132                 void *short_cmd_req = softc->hwrm_short_cmd_req_addr.idi_vaddr;
  133                 uint16_t max_msg_len;
  134 
  135                 /* Set boundary for maximum extended request length for short
  136                  * cmd format. If passed up from device use the max supported
  137                  * internal req length.
  138                  */
  139 
  140                 max_msg_len = softc->hwrm_max_ext_req_len;
  141 
  142 
  143                 memcpy(short_cmd_req, req, msg_len);
  144                 if (msg_len < max_msg_len)
  145                         memset((uint8_t *) short_cmd_req + msg_len, 0,
  146                                 max_msg_len - msg_len);
  147 
  148                 short_input.req_type = req->req_type;
  149                 short_input.signature =
  150                     htole16(HWRM_SHORT_INPUT_SIGNATURE_SHORT_CMD);
  151                 short_input.size = htole16(msg_len);
  152                 short_input.req_addr =
  153                     htole64(softc->hwrm_short_cmd_req_addr.idi_paddr);
  154 
  155                 data = (uint32_t *)&short_input;
  156                 msg_len = sizeof(short_input);
  157 
  158                 /* Sync memory write before updating doorbell */
  159                 wmb();
  160 
  161                 max_req_len = BNXT_HWRM_SHORT_REQ_LEN;
  162         }
  163 
  164         /* Write request msg to hwrm channel */
  165         for (i = 0; i < msg_len; i += 4) {
  166                 bus_space_write_4(softc->hwrm_bar.tag,
  167                                   softc->hwrm_bar.handle,
  168                                   i, *data);
  169                 data++;
  170         }
  171 
  172         /* Clear to the end of the request buffer */
  173         for (i = msg_len; i < max_req_len; i += 4)
  174                 bus_space_write_4(softc->hwrm_bar.tag, softc->hwrm_bar.handle,
  175                     i, 0);
  176 
  177         /* Ring channel doorbell */
  178         bus_space_write_4(softc->hwrm_bar.tag,
  179                           softc->hwrm_bar.handle,
  180                           0x100, htole32(1));
  181 
  182         /* Check if response len is updated */
  183         for (i = 0; i < softc->hwrm_cmd_timeo; i++) {
  184                 if (resp->resp_len && resp->resp_len <= 4096)
  185                         break;
  186                 DELAY(1000);
  187         }
  188         if (i >= softc->hwrm_cmd_timeo) {
  189                 device_printf(softc->dev,
  190                     "Timeout sending %s: (timeout: %u) seq: %d\n",
  191                     GET_HWRM_REQ_TYPE(req->req_type), softc->hwrm_cmd_timeo,
  192                     le16toh(req->seq_id));
  193                 return ETIMEDOUT;
  194         }
  195         /* Last byte of resp contains the valid key */
  196         valid = (uint8_t *)resp + resp->resp_len - 1;
  197         for (i = 0; i < softc->hwrm_cmd_timeo; i++) {
  198                 if (*valid == HWRM_RESP_VALID_KEY)
  199                         break;
  200                 DELAY(1000);
  201         }
  202         if (i >= softc->hwrm_cmd_timeo) {
  203                 device_printf(softc->dev, "Timeout sending %s: "
  204                     "(timeout: %u) msg {0x%x 0x%x} len:%d v: %d\n",
  205                     GET_HWRM_REQ_TYPE(req->req_type),
  206                     softc->hwrm_cmd_timeo, le16toh(req->req_type),
  207                     le16toh(req->seq_id), msg_len,
  208                     *valid);
  209                 return ETIMEDOUT;
  210         }
  211 
  212         err = le16toh(resp->error_code);
  213         if (err) {
  214                 /* HWRM_ERR_CODE_FAIL is a "normal" error, don't log */
  215                 if (err != HWRM_ERR_CODE_FAIL) {
  216                         device_printf(softc->dev,
  217                             "%s command returned %s error.\n",
  218                             GET_HWRM_REQ_TYPE(req->req_type),
  219                             GET_HWRM_ERROR_CODE(err));
  220                 }
  221                 return bnxt_hwrm_err_map(err);
  222         }
  223 
  224         return 0;
  225 }
  226 
  227 static int
  228 hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
  229 {
  230         int rc;
  231 
  232         BNXT_HWRM_LOCK(softc);
  233         rc = _hwrm_send_message(softc, msg, msg_len);
  234         BNXT_HWRM_UNLOCK(softc);
  235         return rc;
  236 }
  237 
  238 int
  239 bnxt_hwrm_queue_qportcfg(struct bnxt_softc *softc)
  240 {
  241         int rc = 0;
  242         struct hwrm_queue_qportcfg_input req = {0};
  243         struct hwrm_queue_qportcfg_output *resp =
  244             (void *)softc->hwrm_cmd_resp.idi_vaddr;
  245         uint8_t i, j, *qptr;
  246         bool no_rdma;
  247 
  248         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_QPORTCFG);
  249 
  250         BNXT_HWRM_LOCK(softc);
  251         rc = _hwrm_send_message(softc, &req, sizeof(req));
  252         if (rc)
  253                 goto qportcfg_exit;
  254 
  255         if (!resp->max_configurable_queues) {
  256                 rc = -EINVAL;
  257                 goto qportcfg_exit;
  258         }
  259         softc->max_tc = resp->max_configurable_queues;
  260         softc->max_lltc = resp->max_configurable_lossless_queues;
  261         if (softc->max_tc > BNXT_MAX_COS_QUEUE)
  262                 softc->max_tc = BNXT_MAX_COS_QUEUE;
  263 
  264         /* Currently no RDMA support */
  265         no_rdma = true;
  266 
  267         qptr = &resp->queue_id0;
  268         for (i = 0, j = 0; i < softc->max_tc; i++) {
  269                 softc->q_info[j].id = *qptr;
  270                 softc->q_ids[i] = *qptr++;
  271                 softc->q_info[j].profile = *qptr++;
  272                 softc->tc_to_qidx[j] = j;
  273                 if (!BNXT_CNPQ(softc->q_info[j].profile) ||
  274                                 (no_rdma && BNXT_PF(softc)))
  275                         j++;
  276         }
  277         softc->max_q = softc->max_tc;
  278         softc->max_tc = max_t(uint32_t, j, 1);
  279 
  280         if (resp->queue_cfg_info & HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG)
  281                 softc->max_tc = 1;
  282 
  283         if (softc->max_lltc > softc->max_tc)
  284                 softc->max_lltc = softc->max_tc;
  285 
  286 qportcfg_exit:
  287         BNXT_HWRM_UNLOCK(softc);
  288         return rc;
  289 }
  290 
  291 int bnxt_hwrm_func_backing_store_qcaps(struct bnxt_softc *softc)
  292 {
  293         struct hwrm_func_backing_store_qcaps_input req = {0};
  294         struct hwrm_func_backing_store_qcaps_output *resp =
  295             (void *)softc->hwrm_cmd_resp.idi_vaddr;
  296         int rc;
  297 
  298         if (softc->hwrm_spec_code < 0x10902 || BNXT_VF(softc) || softc->ctx_mem)
  299                 return 0;
  300 
  301         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_BACKING_STORE_QCAPS);
  302         BNXT_HWRM_LOCK(softc);
  303         rc = _hwrm_send_message(softc, &req, sizeof(req));
  304         if (!rc) {
  305                 struct bnxt_ctx_pg_info *ctx_pg;
  306                 struct bnxt_ctx_mem_info *ctx;
  307                 int i;
  308 
  309                 ctx = malloc(sizeof(*ctx), M_DEVBUF, M_NOWAIT | M_ZERO);
  310                 if (!ctx) {
  311                         rc = -ENOMEM;
  312                         goto ctx_err;
  313                 }
  314                 ctx_pg = malloc(sizeof(*ctx_pg) * (softc->max_q + 1),
  315                                 M_DEVBUF, M_NOWAIT | M_ZERO);
  316                 if (!ctx_pg) {
  317                         free(ctx, M_DEVBUF);
  318                         rc = -ENOMEM;
  319                         goto ctx_err;
  320                 }
  321                 for (i = 0; i < softc->max_q + 1; i++, ctx_pg++)
  322                         ctx->tqm_mem[i] = ctx_pg;
  323 
  324                 softc->ctx_mem = ctx;
  325                 ctx->qp_max_entries = le32toh(resp->qp_max_entries);
  326                 ctx->qp_min_qp1_entries = le16toh(resp->qp_min_qp1_entries);
  327                 ctx->qp_max_l2_entries = le16toh(resp->qp_max_l2_entries);
  328                 ctx->qp_entry_size = le16toh(resp->qp_entry_size);
  329                 ctx->srq_max_l2_entries = le16toh(resp->srq_max_l2_entries);
  330                 ctx->srq_max_entries = le32toh(resp->srq_max_entries);
  331                 ctx->srq_entry_size = le16toh(resp->srq_entry_size);
  332                 ctx->cq_max_l2_entries = le16toh(resp->cq_max_l2_entries);
  333                 ctx->cq_max_entries = le32toh(resp->cq_max_entries);
  334                 ctx->cq_entry_size = le16toh(resp->cq_entry_size);
  335                 ctx->vnic_max_vnic_entries =
  336                         le16toh(resp->vnic_max_vnic_entries);
  337                 ctx->vnic_max_ring_table_entries =
  338                         le16toh(resp->vnic_max_ring_table_entries);
  339                 ctx->vnic_entry_size = le16toh(resp->vnic_entry_size);
  340                 ctx->stat_max_entries = le32toh(resp->stat_max_entries);
  341                 ctx->stat_entry_size = le16toh(resp->stat_entry_size);
  342                 ctx->tqm_entry_size = le16toh(resp->tqm_entry_size);
  343                 ctx->tqm_min_entries_per_ring =
  344                         le32toh(resp->tqm_min_entries_per_ring);
  345                 ctx->tqm_max_entries_per_ring =
  346                         le32toh(resp->tqm_max_entries_per_ring);
  347                 ctx->tqm_entries_multiple = resp->tqm_entries_multiple;
  348                 if (!ctx->tqm_entries_multiple)
  349                         ctx->tqm_entries_multiple = 1;
  350                 ctx->mrav_max_entries = le32toh(resp->mrav_max_entries);
  351                 ctx->mrav_entry_size = le16toh(resp->mrav_entry_size);
  352                 ctx->tim_entry_size = le16toh(resp->tim_entry_size);
  353                 ctx->tim_max_entries = le32toh(resp->tim_max_entries);
  354                 ctx->ctx_kind_initializer = resp->ctx_kind_initializer;
  355         } else {
  356                 rc = 0;
  357         }
  358 ctx_err:
  359         BNXT_HWRM_UNLOCK(softc);
  360         return rc;
  361 }
  362 
  363 #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_DFLT_ENABLES                 \
  364         (HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_QP |                \
  365          HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_SRQ |               \
  366          HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_CQ |                \
  367          HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_VNIC |              \
  368          HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_STAT)
  369 
  370 static void bnxt_hwrm_set_pg_attr(struct bnxt_ring_mem_info *rmem, uint8_t *pg_attr,
  371                                   uint64_t *pg_dir)
  372 {
  373         uint8_t pg_size = 0;
  374 
  375         if (BNXT_PAGE_SHIFT == 13)
  376                 pg_size = 1 << 4;
  377         else if (BNXT_PAGE_SIZE == 16)
  378                 pg_size = 2 << 4;
  379 
  380         *pg_attr = pg_size;
  381         if (rmem->depth >= 1) {
  382                 if (rmem->depth == 2)
  383                         *pg_attr |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_LVL_2;
  384                 else
  385                         *pg_attr |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_LVL_1;
  386                 *pg_dir = htole64(rmem->pg_tbl.idi_paddr);
  387         } else {
  388                 *pg_dir = htole64(rmem->pg_arr[0].idi_paddr);
  389         }
  390 }
  391 
  392 int bnxt_hwrm_func_backing_store_cfg(struct bnxt_softc *softc, uint32_t enables)
  393 {
  394         struct hwrm_func_backing_store_cfg_input req = {0};
  395         struct bnxt_ctx_mem_info *ctx = softc->ctx_mem;
  396         struct bnxt_ctx_pg_info *ctx_pg;
  397         uint32_t *num_entries, req_len = sizeof(req);
  398         uint64_t *pg_dir;
  399         uint8_t *pg_attr;
  400         int i, rc;
  401         uint32_t ena;
  402 
  403         if (!ctx)
  404                 return 0;
  405 
  406         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_BACKING_STORE_CFG);
  407         req.enables = htole32(enables);
  408 
  409         if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_QP) {
  410                 ctx_pg = &ctx->qp_mem;
  411                 req.qp_num_entries = htole32(ctx_pg->entries);
  412                 req.qp_num_qp1_entries = htole16(ctx->qp_min_qp1_entries);
  413                 req.qp_num_l2_entries = htole16(ctx->qp_max_l2_entries);
  414                 req.qp_entry_size = htole16(ctx->qp_entry_size);
  415                 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem,
  416                                 &req.qpc_pg_size_qpc_lvl,
  417                                 &req.qpc_page_dir);
  418         }
  419         if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_SRQ) {
  420                 ctx_pg = &ctx->srq_mem;
  421                 req.srq_num_entries = htole32(ctx_pg->entries);
  422                 req.srq_num_l2_entries = htole16(ctx->srq_max_l2_entries);
  423                 req.srq_entry_size = htole16(ctx->srq_entry_size);
  424                 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem,
  425                                 &req.srq_pg_size_srq_lvl,
  426                                 &req.srq_page_dir);
  427         }
  428         if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_CQ) {
  429                 ctx_pg = &ctx->cq_mem;
  430                 req.cq_num_entries = htole32(ctx_pg->entries);
  431                 req.cq_num_l2_entries = htole16(ctx->cq_max_l2_entries);
  432                 req.cq_entry_size = htole16(ctx->cq_entry_size);
  433                 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, &req.cq_pg_size_cq_lvl,
  434                                 &req.cq_page_dir);
  435         }
  436         if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_MRAV) {
  437                 ctx_pg = &ctx->mrav_mem;
  438                 req.mrav_num_entries = htole32(ctx_pg->entries);
  439                 req.mrav_entry_size = htole16(ctx->mrav_entry_size);
  440                 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem,
  441                                 &req.mrav_pg_size_mrav_lvl,
  442                                 &req.mrav_page_dir);
  443         }
  444         if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TIM) {
  445                 ctx_pg = &ctx->tim_mem;
  446                 req.tim_num_entries = htole32(ctx_pg->entries);
  447                 req.tim_entry_size = htole16(ctx->tim_entry_size);
  448                 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem,
  449                                 &req.tim_pg_size_tim_lvl,
  450                                 &req.tim_page_dir);
  451         }
  452         if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_VNIC) {
  453                 ctx_pg = &ctx->vnic_mem;
  454                 req.vnic_num_vnic_entries =
  455                         htole16(ctx->vnic_max_vnic_entries);
  456                 req.vnic_num_ring_table_entries =
  457                         htole16(ctx->vnic_max_ring_table_entries);
  458                 req.vnic_entry_size = htole16(ctx->vnic_entry_size);
  459                 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem,
  460                                 &req.vnic_pg_size_vnic_lvl,
  461                                 &req.vnic_page_dir);
  462         }
  463         if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_STAT) {
  464                 ctx_pg = &ctx->stat_mem;
  465                 req.stat_num_entries = htole32(ctx->stat_max_entries);
  466                 req.stat_entry_size = htole16(ctx->stat_entry_size);
  467                 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem,
  468                                 &req.stat_pg_size_stat_lvl,
  469                                 &req.stat_page_dir);
  470         }
  471         for (i = 0, num_entries = &req.tqm_sp_num_entries,
  472                         pg_attr = &req.tqm_sp_pg_size_tqm_sp_lvl,
  473                         pg_dir = &req.tqm_sp_page_dir,
  474                         ena = HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_SP;
  475                         i < 9; i++, num_entries++, pg_attr++, pg_dir++, ena <<= 1) {
  476                 if (!(enables & ena))
  477                         continue;
  478 
  479                 req.tqm_entry_size = htole16(ctx->tqm_entry_size);
  480                 ctx_pg = ctx->tqm_mem[i];
  481                 *num_entries = htole32(ctx_pg->entries);
  482                 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, pg_attr, pg_dir);
  483         }
  484 
  485         if (req_len > softc->hwrm_max_ext_req_len)
  486                 req_len = BNXT_BACKING_STORE_CFG_LEGACY_LEN;
  487 
  488         rc = hwrm_send_message(softc, &req, req_len);
  489         if (rc)
  490                 rc = -EIO;
  491         return rc;
  492 }
  493 
  494 int bnxt_hwrm_func_resc_qcaps(struct bnxt_softc *softc, bool all)
  495 {
  496         struct hwrm_func_resource_qcaps_output *resp =
  497             (void *)softc->hwrm_cmd_resp.idi_vaddr;
  498         struct hwrm_func_resource_qcaps_input req = {0};
  499         struct bnxt_hw_resc *hw_resc = &softc->hw_resc;
  500         int rc;
  501 
  502         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_RESOURCE_QCAPS);
  503         req.fid = htole16(0xffff);
  504 
  505         BNXT_HWRM_LOCK(softc);
  506         rc = _hwrm_send_message(softc, &req, sizeof(req));
  507         if (rc) {
  508                 rc = -EIO;
  509                 goto hwrm_func_resc_qcaps_exit;
  510         }
  511 
  512         hw_resc->max_tx_sch_inputs = le16toh(resp->max_tx_scheduler_inputs);
  513         if (!all)
  514                 goto hwrm_func_resc_qcaps_exit;
  515 
  516         hw_resc->min_rsscos_ctxs = le16toh(resp->min_rsscos_ctx);
  517         hw_resc->max_rsscos_ctxs = le16toh(resp->max_rsscos_ctx);
  518         hw_resc->min_cp_rings = le16toh(resp->min_cmpl_rings);
  519         hw_resc->max_cp_rings = le16toh(resp->max_cmpl_rings);
  520         hw_resc->min_tx_rings = le16toh(resp->min_tx_rings);
  521         hw_resc->max_tx_rings = le16toh(resp->max_tx_rings);
  522         hw_resc->min_rx_rings = le16toh(resp->min_rx_rings);
  523         hw_resc->max_rx_rings = le16toh(resp->max_rx_rings);
  524         hw_resc->min_hw_ring_grps = le16toh(resp->min_hw_ring_grps);
  525         hw_resc->max_hw_ring_grps = le16toh(resp->max_hw_ring_grps);
  526         hw_resc->min_l2_ctxs = le16toh(resp->min_l2_ctxs);
  527         hw_resc->max_l2_ctxs = le16toh(resp->max_l2_ctxs);
  528         hw_resc->min_vnics = le16toh(resp->min_vnics);
  529         hw_resc->max_vnics = le16toh(resp->max_vnics);
  530         hw_resc->min_stat_ctxs = le16toh(resp->min_stat_ctx);
  531         hw_resc->max_stat_ctxs = le16toh(resp->max_stat_ctx);
  532 
  533         if (BNXT_CHIP_P5(softc)) {
  534                 hw_resc->max_nqs = le16toh(resp->max_msix);
  535                 hw_resc->max_hw_ring_grps = hw_resc->max_rx_rings;
  536         }
  537 
  538 hwrm_func_resc_qcaps_exit:
  539         BNXT_HWRM_UNLOCK(softc);
  540         return rc;
  541 }
  542 
  543 int
  544 bnxt_hwrm_passthrough(struct bnxt_softc *softc, void *req, uint32_t req_len,
  545                 void *resp, uint32_t resp_len, uint32_t app_timeout)
  546 {
  547         int rc = 0;
  548         void *output = (void *)softc->hwrm_cmd_resp.idi_vaddr;
  549         struct input *input = req;
  550         uint32_t old_timeo;
  551 
  552         input->resp_addr = htole64(softc->hwrm_cmd_resp.idi_paddr);
  553         BNXT_HWRM_LOCK(softc);
  554         old_timeo = softc->hwrm_cmd_timeo;
  555         if (input->req_type == HWRM_NVM_INSTALL_UPDATE) 
  556                 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
  557         else
  558                 softc->hwrm_cmd_timeo = max(app_timeout, softc->hwrm_cmd_timeo);
  559         rc = _hwrm_send_message(softc, req, req_len);
  560         softc->hwrm_cmd_timeo = old_timeo;
  561         if (rc) {
  562                 device_printf(softc->dev, "%s: %s command failed with rc: 0x%x\n",
  563                               __FUNCTION__, GET_HWRM_REQ_TYPE(input->req_type), rc);
  564                 goto fail;
  565         }
  566 
  567         memcpy(resp, output, resp_len);
  568 fail:
  569         BNXT_HWRM_UNLOCK(softc);
  570         return rc;
  571 }
  572 
  573 
  574 int
  575 bnxt_hwrm_ver_get(struct bnxt_softc *softc)
  576 {
  577         struct hwrm_ver_get_input       req = {0};
  578         struct hwrm_ver_get_output      *resp =
  579             (void *)softc->hwrm_cmd_resp.idi_vaddr;
  580         int                             rc;
  581         const char nastr[] = "<not installed>";
  582         const char naver[] = "<N/A>";
  583         uint32_t dev_caps_cfg;
  584         uint16_t fw_maj, fw_min, fw_bld, fw_rsv, len;
  585 
  586         softc->hwrm_max_req_len = HWRM_MAX_REQ_LEN;
  587         softc->hwrm_cmd_timeo = 1000;
  588         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VER_GET);
  589 
  590         req.hwrm_intf_maj = HWRM_VERSION_MAJOR;
  591         req.hwrm_intf_min = HWRM_VERSION_MINOR;
  592         req.hwrm_intf_upd = HWRM_VERSION_UPDATE;
  593 
  594         BNXT_HWRM_LOCK(softc);
  595         rc = _hwrm_send_message(softc, &req, sizeof(req));
  596         if (rc)
  597                 goto fail;
  598 
  599         snprintf(softc->ver_info->hwrm_if_ver, BNXT_VERSTR_SIZE, "%d.%d.%d",
  600             resp->hwrm_intf_maj_8b, resp->hwrm_intf_min_8b, resp->hwrm_intf_upd_8b);
  601         softc->ver_info->hwrm_if_major = resp->hwrm_intf_maj_8b;
  602         softc->ver_info->hwrm_if_minor = resp->hwrm_intf_min_8b;
  603         softc->ver_info->hwrm_if_update = resp->hwrm_intf_upd_8b;
  604         snprintf(softc->ver_info->hwrm_fw_ver, BNXT_VERSTR_SIZE, "%d.%d.%d",
  605             resp->hwrm_fw_major, resp->hwrm_fw_minor, resp->hwrm_fw_build);
  606         strlcpy(softc->ver_info->driver_hwrm_if_ver, HWRM_VERSION_STR,
  607             BNXT_VERSTR_SIZE);
  608         strlcpy(softc->ver_info->hwrm_fw_name, resp->hwrm_fw_name,
  609             BNXT_NAME_SIZE);
  610 
  611          softc->hwrm_spec_code = resp->hwrm_intf_maj_8b << 16 |
  612                              resp->hwrm_intf_min_8b << 8 |
  613                              resp->hwrm_intf_upd_8b;
  614         if (resp->hwrm_intf_maj_8b < 1) {
  615                  device_printf(softc->dev, "HWRM interface %d.%d.%d is older "
  616                                "than 1.0.0.\n", resp->hwrm_intf_maj_8b,
  617                                resp->hwrm_intf_min_8b, resp->hwrm_intf_upd_8b);
  618                  device_printf(softc->dev, "Please update firmware with HWRM "
  619                                 "interface 1.0.0 or newer.\n");
  620          }
  621         if (resp->mgmt_fw_major == 0 && resp->mgmt_fw_minor == 0 &&
  622             resp->mgmt_fw_build == 0) {
  623                 strlcpy(softc->ver_info->mgmt_fw_ver, naver, BNXT_VERSTR_SIZE);
  624                 strlcpy(softc->ver_info->mgmt_fw_name, nastr, BNXT_NAME_SIZE);
  625         }
  626         else {
  627                 snprintf(softc->ver_info->mgmt_fw_ver, BNXT_VERSTR_SIZE,
  628                     "%d.%d.%d", resp->mgmt_fw_major, resp->mgmt_fw_minor,
  629                     resp->mgmt_fw_build);
  630                 strlcpy(softc->ver_info->mgmt_fw_name, resp->mgmt_fw_name,
  631                     BNXT_NAME_SIZE);
  632         }
  633         if (resp->netctrl_fw_major == 0 && resp->netctrl_fw_minor == 0 &&
  634             resp->netctrl_fw_build == 0) {
  635                 strlcpy(softc->ver_info->netctrl_fw_ver, naver,
  636                     BNXT_VERSTR_SIZE);
  637                 strlcpy(softc->ver_info->netctrl_fw_name, nastr,
  638                     BNXT_NAME_SIZE);
  639         }
  640         else {
  641                 snprintf(softc->ver_info->netctrl_fw_ver, BNXT_VERSTR_SIZE,
  642                     "%d.%d.%d", resp->netctrl_fw_major, resp->netctrl_fw_minor,
  643                     resp->netctrl_fw_build);
  644                 strlcpy(softc->ver_info->netctrl_fw_name, resp->netctrl_fw_name,
  645                     BNXT_NAME_SIZE);
  646         }
  647         if (resp->roce_fw_major == 0 && resp->roce_fw_minor == 0 &&
  648             resp->roce_fw_build == 0) {
  649                 strlcpy(softc->ver_info->roce_fw_ver, naver, BNXT_VERSTR_SIZE);
  650                 strlcpy(softc->ver_info->roce_fw_name, nastr, BNXT_NAME_SIZE);
  651         }
  652         else {
  653                 snprintf(softc->ver_info->roce_fw_ver, BNXT_VERSTR_SIZE,
  654                     "%d.%d.%d", resp->roce_fw_major, resp->roce_fw_minor,
  655                     resp->roce_fw_build);
  656                 strlcpy(softc->ver_info->roce_fw_name, resp->roce_fw_name,
  657                     BNXT_NAME_SIZE);
  658         }
  659 
  660         fw_maj = le32toh(resp->hwrm_fw_major);
  661         if (softc->hwrm_spec_code > 0x10803 && fw_maj) {
  662                 fw_min = le16toh(resp->hwrm_fw_minor);
  663                 fw_bld = le16toh(resp->hwrm_fw_build);
  664                 fw_rsv = le16toh(resp->hwrm_fw_patch);
  665                 len = FW_VER_STR_LEN;
  666         } else {
  667                 fw_maj = resp->hwrm_fw_maj_8b;
  668                 fw_min = resp->hwrm_fw_min_8b;
  669                 fw_bld = resp->hwrm_fw_bld_8b;
  670                 fw_rsv = resp->hwrm_fw_rsvd_8b;
  671                 len = BC_HWRM_STR_LEN;
  672         }
  673 
  674         snprintf (softc->ver_info->fw_ver_str, len, "%d.%d.%d.%d",
  675                         fw_maj, fw_min, fw_bld, fw_rsv);
  676 
  677         if (strlen(resp->active_pkg_name)) {
  678                 int fw_ver_len = strlen (softc->ver_info->fw_ver_str);
  679 
  680                 snprintf(softc->ver_info->fw_ver_str + fw_ver_len,
  681                                 FW_VER_STR_LEN - fw_ver_len - 1, "/pkg %s",
  682                                 resp->active_pkg_name);
  683         }
  684 
  685         softc->ver_info->chip_num = le16toh(resp->chip_num);
  686         softc->ver_info->chip_rev = resp->chip_rev;
  687         softc->ver_info->chip_metal = resp->chip_metal;
  688         softc->ver_info->chip_bond_id = resp->chip_bond_id;
  689         softc->ver_info->chip_type = resp->chip_platform_type;
  690 
  691         if (resp->hwrm_intf_maj_8b >= 1) {
  692                 softc->hwrm_max_req_len = le16toh(resp->max_req_win_len);
  693                 softc->hwrm_max_ext_req_len = le16toh(resp->max_ext_req_len);
  694         }
  695 #define DFLT_HWRM_CMD_TIMEOUT           500
  696         softc->hwrm_cmd_timeo = le16toh(resp->def_req_timeout);
  697         if (!softc->hwrm_cmd_timeo)
  698                 softc->hwrm_cmd_timeo = DFLT_HWRM_CMD_TIMEOUT;
  699         
  700         dev_caps_cfg = le32toh(resp->dev_caps_cfg);
  701         if ((dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
  702             (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED))
  703                 softc->flags |= BNXT_FLAG_SHORT_CMD;
  704 
  705 fail:
  706         BNXT_HWRM_UNLOCK(softc);
  707         return rc;
  708 }
  709 
  710 int
  711 bnxt_hwrm_func_drv_rgtr(struct bnxt_softc *softc)
  712 {
  713         struct hwrm_func_drv_rgtr_input req = {0};
  714 
  715         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_DRV_RGTR);
  716 
  717         req.enables = htole32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
  718             HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_OS_TYPE);
  719         req.os_type = htole16(HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD);
  720 
  721         req.ver_maj = __FreeBSD_version / 100000;
  722         req.ver_min = (__FreeBSD_version / 1000) % 100;
  723         req.ver_upd = (__FreeBSD_version / 100) % 10;
  724 
  725         return hwrm_send_message(softc, &req, sizeof(req));
  726 }
  727 
  728 int
  729 bnxt_hwrm_func_drv_unrgtr(struct bnxt_softc *softc, bool shutdown)
  730 {
  731         struct hwrm_func_drv_unrgtr_input req = {0};
  732 
  733         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_DRV_UNRGTR);
  734         if (shutdown == true)
  735                 req.flags |=
  736                     HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN;
  737         return hwrm_send_message(softc, &req, sizeof(req));
  738 }
  739 
  740 static inline int
  741 _is_valid_ether_addr(uint8_t *addr)
  742 {
  743         char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
  744 
  745         if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN)))
  746                 return (FALSE);
  747 
  748         return (TRUE);
  749 }
  750 
  751 static inline void
  752 get_random_ether_addr(uint8_t *addr)
  753 {
  754         uint8_t temp[ETHER_ADDR_LEN];
  755 
  756         arc4rand(&temp, sizeof(temp), 0);
  757         temp[0] &= 0xFE;
  758         temp[0] |= 0x02;
  759         bcopy(temp, addr, sizeof(temp));
  760 }
  761 
  762 int
  763 bnxt_hwrm_func_qcaps(struct bnxt_softc *softc)
  764 {
  765         int rc = 0;
  766         struct hwrm_func_qcaps_input req = {0};
  767         struct hwrm_func_qcaps_output *resp =
  768             (void *)softc->hwrm_cmd_resp.idi_vaddr;
  769         struct bnxt_func_info *func = &softc->func;
  770 
  771         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_QCAPS);
  772         req.fid = htole16(0xffff);
  773 
  774         BNXT_HWRM_LOCK(softc);
  775         rc = _hwrm_send_message(softc, &req, sizeof(req));
  776         if (rc)
  777                 goto fail;
  778 
  779         if (resp->flags &
  780             htole32(HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED))
  781                 softc->flags |= BNXT_FLAG_WOL_CAP;
  782 
  783         func->fw_fid = le16toh(resp->fid);
  784         memcpy(func->mac_addr, resp->mac_address, ETHER_ADDR_LEN);
  785         func->max_rsscos_ctxs = le16toh(resp->max_rsscos_ctx);
  786         func->max_cp_rings = le16toh(resp->max_cmpl_rings);
  787         func->max_tx_rings = le16toh(resp->max_tx_rings);
  788         func->max_rx_rings = le16toh(resp->max_rx_rings);
  789         func->max_hw_ring_grps = le32toh(resp->max_hw_ring_grps);
  790         if (!func->max_hw_ring_grps)
  791                 func->max_hw_ring_grps = func->max_tx_rings;
  792         func->max_l2_ctxs = le16toh(resp->max_l2_ctxs);
  793         func->max_vnics = le16toh(resp->max_vnics);
  794         func->max_stat_ctxs = le16toh(resp->max_stat_ctx);
  795         if (BNXT_PF(softc)) {
  796                 struct bnxt_pf_info *pf = &softc->pf;
  797 
  798                 pf->port_id = le16toh(resp->port_id);
  799                 pf->first_vf_id = le16toh(resp->first_vf_id);
  800                 pf->max_vfs = le16toh(resp->max_vfs);
  801                 pf->max_encap_records = le32toh(resp->max_encap_records);
  802                 pf->max_decap_records = le32toh(resp->max_decap_records);
  803                 pf->max_tx_em_flows = le32toh(resp->max_tx_em_flows);
  804                 pf->max_tx_wm_flows = le32toh(resp->max_tx_wm_flows);
  805                 pf->max_rx_em_flows = le32toh(resp->max_rx_em_flows);
  806                 pf->max_rx_wm_flows = le32toh(resp->max_rx_wm_flows);
  807         }
  808         if (!_is_valid_ether_addr(func->mac_addr)) {
  809                 device_printf(softc->dev, "Invalid ethernet address, generating random locally administered address\n");
  810                 get_random_ether_addr(func->mac_addr);
  811         }
  812 
  813 fail:
  814         BNXT_HWRM_UNLOCK(softc);
  815         return rc;
  816 }
  817 
  818 int
  819 bnxt_hwrm_func_qcfg(struct bnxt_softc *softc)
  820 {
  821         struct hwrm_func_qcfg_input req = {0};
  822         struct hwrm_func_qcfg_output *resp =
  823             (void *)softc->hwrm_cmd_resp.idi_vaddr;
  824         struct bnxt_func_qcfg *fn_qcfg = &softc->fn_qcfg;
  825         int rc;
  826 
  827         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_QCFG);
  828         req.fid = htole16(0xffff);
  829         BNXT_HWRM_LOCK(softc);
  830         rc = _hwrm_send_message(softc, &req, sizeof(req));
  831         if (rc)
  832                 goto fail;
  833 
  834         fn_qcfg->alloc_completion_rings = le16toh(resp->alloc_cmpl_rings);
  835         fn_qcfg->alloc_tx_rings = le16toh(resp->alloc_tx_rings);
  836         fn_qcfg->alloc_rx_rings = le16toh(resp->alloc_rx_rings);
  837         fn_qcfg->alloc_vnics = le16toh(resp->alloc_vnics);
  838 fail:
  839         BNXT_HWRM_UNLOCK(softc);
  840         return rc;
  841 }
  842 
  843 int
  844 bnxt_hwrm_func_reset(struct bnxt_softc *softc)
  845 {
  846         struct hwrm_func_reset_input req = {0};
  847 
  848         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_RESET);
  849         req.enables = 0;
  850 
  851         return hwrm_send_message(softc, &req, sizeof(req));
  852 }
  853 
  854 static void
  855 bnxt_hwrm_set_link_common(struct bnxt_softc *softc,
  856     struct hwrm_port_phy_cfg_input *req)
  857 {
  858         uint8_t autoneg = softc->link_info.autoneg;
  859         uint16_t fw_link_speed = softc->link_info.req_link_speed;
  860 
  861         if (autoneg & BNXT_AUTONEG_SPEED) {
  862                 req->auto_mode |=
  863                     HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS;
  864 
  865                 req->enables |=
  866                     htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE);
  867                 req->flags |=
  868                     htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG);
  869         } else {
  870                 req->force_link_speed = htole16(fw_link_speed);
  871                 req->flags |= htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE);
  872         }
  873 
  874         /* tell chimp that the setting takes effect immediately */
  875         req->flags |= htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY);
  876 }
  877 
  878 static void
  879 bnxt_hwrm_set_pause_common(struct bnxt_softc *softc,
  880     struct hwrm_port_phy_cfg_input *req)
  881 {
  882         struct bnxt_link_info *link_info = &softc->link_info;
  883 
  884         if (link_info->flow_ctrl.autoneg) {
  885                 req->auto_pause =
  886                     HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE;
  887                 if (link_info->flow_ctrl.rx)
  888                         req->auto_pause |=
  889                             HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
  890                 if (link_info->flow_ctrl.tx)
  891                         req->auto_pause |=
  892                             HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX;
  893                 req->enables |=
  894                     htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE);
  895         } else {
  896                 if (link_info->flow_ctrl.rx)
  897                         req->force_pause |=
  898                             HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
  899                 if (link_info->flow_ctrl.tx)
  900                         req->force_pause |=
  901                             HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX;
  902                 req->enables |=
  903                         htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE);
  904                 req->auto_pause = req->force_pause;
  905                 req->enables |=
  906                     htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE);
  907         }
  908 }
  909 
  910 /* JFV this needs interface connection */
  911 static void
  912 bnxt_hwrm_set_eee(struct bnxt_softc *softc, struct hwrm_port_phy_cfg_input *req)
  913 {
  914         /* struct ethtool_eee *eee = &softc->eee; */
  915         bool    eee_enabled = false;
  916 
  917         if (eee_enabled) {
  918 #if 0
  919                 uint16_t eee_speeds;
  920                 uint32_t flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_ENABLE;
  921 
  922                 if (eee->tx_lpi_enabled)
  923                         flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI;
  924 
  925                 req->flags |= htole32(flags);
  926                 eee_speeds = bnxt_get_fw_auto_link_speeds(eee->advertised);
  927                 req->eee_link_speed_mask = htole16(eee_speeds);
  928                 req->tx_lpi_timer = htole32(eee->tx_lpi_timer);
  929 #endif
  930         } else {
  931                 req->flags |=
  932                     htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_DISABLE);
  933         }
  934 }
  935 
  936 int
  937 bnxt_hwrm_set_link_setting(struct bnxt_softc *softc, bool set_pause,
  938     bool set_eee, bool set_link)
  939 {
  940         struct hwrm_port_phy_cfg_input req = {0};
  941         int rc;
  942 
  943         if (softc->flags & BNXT_FLAG_NPAR)
  944                 return ENOTSUP;
  945 
  946         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_CFG);
  947 
  948         if (set_pause) {
  949                 bnxt_hwrm_set_pause_common(softc, &req);
  950 
  951                 if (softc->link_info.flow_ctrl.autoneg)
  952                         set_link = true;
  953         }
  954 
  955         if (set_link)
  956                 bnxt_hwrm_set_link_common(softc, &req);
  957 
  958         if (set_eee)
  959                 bnxt_hwrm_set_eee(softc, &req);
  960 
  961         BNXT_HWRM_LOCK(softc);
  962         rc = _hwrm_send_message(softc, &req, sizeof(req));
  963 
  964         if (!rc) {
  965                 if (set_pause) {
  966                         /* since changing of 'force pause' setting doesn't
  967                          * trigger any link change event, the driver needs to
  968                          * update the current pause result upon successfully i
  969                          * return of the phy_cfg command */
  970                         if (!softc->link_info.flow_ctrl.autoneg)
  971                                 bnxt_report_link(softc);
  972                 }
  973         }
  974         BNXT_HWRM_UNLOCK(softc);
  975         return rc;
  976 }
  977 
  978 int
  979 bnxt_hwrm_vnic_set_hds(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic)
  980 {
  981         struct hwrm_vnic_plcmodes_cfg_input req = {0};
  982 
  983         if (!BNXT_CHIP_P5(softc))
  984                 return 0;
  985 
  986         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_PLCMODES_CFG);
  987 
  988         /*
  989          * TBD -- Explore these flags
  990          *      1. VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_IPV4
  991          *      2. VNIC_PLCMODES_CFG_REQ_FLAGS_HDS_IPV6
  992          *      3. req.jumbo_thresh
  993          *      4. req.hds_threshold
  994          */
  995         req.flags = htole32(HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
  996         req.vnic_id = htole16(vnic->id);
  997 
  998         return hwrm_send_message(softc, &req, sizeof(req));
  999 }
 1000 
 1001 int
 1002 bnxt_hwrm_vnic_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic)
 1003 {
 1004         struct hwrm_vnic_cfg_input req = {0};
 1005 
 1006         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_CFG);
 1007 
 1008         if (vnic->flags & BNXT_VNIC_FLAG_DEFAULT)
 1009                 req.flags |= htole32(HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT);
 1010         if (vnic->flags & BNXT_VNIC_FLAG_BD_STALL)
 1011                 req.flags |= htole32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE);
 1012         if (vnic->flags & BNXT_VNIC_FLAG_VLAN_STRIP)
 1013                 req.flags |= htole32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE);
 1014         if (BNXT_CHIP_P5 (softc)) {
 1015                 req.default_rx_ring_id =
 1016                         htole16(softc->rx_rings[0].phys_id);
 1017                 req.default_cmpl_ring_id =
 1018                         htole16(softc->rx_cp_rings[0].ring.phys_id);
 1019                 req.enables |=
 1020                         htole32(HWRM_VNIC_CFG_INPUT_ENABLES_DEFAULT_RX_RING_ID |
 1021                             HWRM_VNIC_CFG_INPUT_ENABLES_DEFAULT_CMPL_RING_ID);
 1022                 req.vnic_id = htole16(vnic->id);
 1023         } else {
 1024                 req.enables = htole32(HWRM_VNIC_CFG_INPUT_ENABLES_DFLT_RING_GRP |
 1025                                 HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE);
 1026                 req.vnic_id = htole16(vnic->id);
 1027                 req.dflt_ring_grp = htole16(vnic->def_ring_grp);
 1028         }
 1029         req.rss_rule = htole16(vnic->rss_id);
 1030         req.cos_rule = htole16(vnic->cos_rule);
 1031         req.lb_rule = htole16(vnic->lb_rule);
 1032         req.enables |= htole32(HWRM_VNIC_CFG_INPUT_ENABLES_MRU);
 1033         req.mru = htole16(vnic->mru);
 1034 
 1035         return hwrm_send_message(softc, &req, sizeof(req));
 1036 }
 1037 
 1038 int
 1039 bnxt_hwrm_vnic_free(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic)
 1040 {
 1041         struct hwrm_vnic_free_input req = {0};
 1042         int rc = 0;
 1043 
 1044         if (vnic->id == (uint16_t)HWRM_NA_SIGNATURE)
 1045                 return rc;
 1046 
 1047         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_FREE);
 1048 
 1049         req.vnic_id = htole32(vnic->id);
 1050 
 1051         BNXT_HWRM_LOCK(softc);
 1052         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1053         if (rc)
 1054                 goto fail;
 1055 
 1056 fail:
 1057         BNXT_HWRM_UNLOCK(softc);
 1058         return (rc);
 1059 }
 1060 
 1061 int
 1062 bnxt_hwrm_vnic_alloc(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic)
 1063 {
 1064         struct hwrm_vnic_alloc_input req = {0};
 1065         struct hwrm_vnic_alloc_output *resp =
 1066             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1067         int rc;
 1068 
 1069         if (vnic->id != (uint16_t)HWRM_NA_SIGNATURE) {
 1070                 device_printf(softc->dev,
 1071                     "Attempt to re-allocate vnic %04x\n", vnic->id);
 1072                 return EDOOFUS;
 1073         }
 1074 
 1075         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_ALLOC);
 1076 
 1077         if (vnic->flags & BNXT_VNIC_FLAG_DEFAULT)
 1078                 req.flags = htole32(HWRM_VNIC_ALLOC_INPUT_FLAGS_DEFAULT);
 1079 
 1080         BNXT_HWRM_LOCK(softc);
 1081         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1082         if (rc)
 1083                 goto fail;
 1084 
 1085         vnic->id = le32toh(resp->vnic_id);
 1086 
 1087 fail:
 1088         BNXT_HWRM_UNLOCK(softc);
 1089         return (rc);
 1090 }
 1091 
 1092 int
 1093 bnxt_hwrm_vnic_ctx_free(struct bnxt_softc *softc, uint16_t ctx_id)
 1094 {
 1095         struct hwrm_vnic_rss_cos_lb_ctx_free_input req = {0};
 1096         int rc = 0;
 1097 
 1098         if (ctx_id == (uint16_t)HWRM_NA_SIGNATURE)
 1099                 return rc;
 1100 
 1101         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_RSS_COS_LB_CTX_FREE);
 1102         req.rss_cos_lb_ctx_id = htole16(ctx_id);
 1103         BNXT_HWRM_LOCK(softc);
 1104         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1105         if (rc)
 1106                 goto fail;
 1107 
 1108 fail:
 1109         BNXT_HWRM_UNLOCK(softc);
 1110         return rc;
 1111 }
 1112 
 1113 int
 1114 bnxt_hwrm_vnic_ctx_alloc(struct bnxt_softc *softc, uint16_t *ctx_id)
 1115 {
 1116         struct hwrm_vnic_rss_cos_lb_ctx_alloc_input req = {0};
 1117         struct hwrm_vnic_rss_cos_lb_ctx_alloc_output *resp =
 1118             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1119         int rc;
 1120 
 1121         if (*ctx_id != (uint16_t)HWRM_NA_SIGNATURE) {
 1122                 device_printf(softc->dev,
 1123                     "Attempt to re-allocate vnic ctx %04x\n", *ctx_id);
 1124                 return EDOOFUS;
 1125         }
 1126 
 1127         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_RSS_COS_LB_CTX_ALLOC);
 1128 
 1129         BNXT_HWRM_LOCK(softc);
 1130         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1131         if (rc)
 1132                 goto fail;
 1133 
 1134         *ctx_id = le32toh(resp->rss_cos_lb_ctx_id);
 1135 
 1136 fail:
 1137         BNXT_HWRM_UNLOCK(softc);
 1138         return (rc);
 1139 }
 1140 
 1141 int
 1142 bnxt_hwrm_ring_grp_alloc(struct bnxt_softc *softc, struct bnxt_grp_info *grp)
 1143 {
 1144         struct hwrm_ring_grp_alloc_input req = {0};
 1145         struct hwrm_ring_grp_alloc_output *resp;
 1146         int rc = 0;
 1147 
 1148         if (grp->grp_id != (uint16_t)HWRM_NA_SIGNATURE) {
 1149                 device_printf(softc->dev,
 1150                     "Attempt to re-allocate ring group %04x\n", grp->grp_id);
 1151                 return EDOOFUS;
 1152         }
 1153 
 1154         if (BNXT_CHIP_P5 (softc))
 1155                 return 0;
 1156 
 1157         resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1158         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_GRP_ALLOC);
 1159         req.cr = htole16(grp->cp_ring_id);
 1160         req.rr = htole16(grp->rx_ring_id);
 1161         req.ar = htole16(grp->ag_ring_id);
 1162         req.sc = htole16(grp->stats_ctx);
 1163 
 1164         BNXT_HWRM_LOCK(softc);
 1165         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1166         if (rc)
 1167                 goto fail;
 1168 
 1169         grp->grp_id = le32toh(resp->ring_group_id);
 1170 
 1171 fail:
 1172         BNXT_HWRM_UNLOCK(softc);
 1173         return rc;
 1174 }
 1175 
 1176 int
 1177 bnxt_hwrm_ring_grp_free(struct bnxt_softc *softc, struct bnxt_grp_info *grp)
 1178 {
 1179         struct hwrm_ring_grp_free_input req = {0};
 1180         int rc = 0;
 1181 
 1182         if (grp->grp_id == (uint16_t)HWRM_NA_SIGNATURE)
 1183                 return 0;
 1184 
 1185         if (BNXT_CHIP_P5 (softc))
 1186                 return 0;
 1187 
 1188         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_GRP_FREE);
 1189 
 1190         req.ring_group_id = htole32(grp->grp_id);
 1191 
 1192         BNXT_HWRM_LOCK(softc);
 1193         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1194         if (rc)
 1195                 goto fail;
 1196 
 1197 fail:
 1198         BNXT_HWRM_UNLOCK(softc);
 1199         return rc;
 1200 }
 1201 
 1202 int bnxt_hwrm_ring_free(struct bnxt_softc *softc, uint32_t ring_type,
 1203                 struct bnxt_ring *ring, int cmpl_ring_id)
 1204 {
 1205         struct hwrm_ring_free_input req = {0};
 1206         struct hwrm_ring_free_output *resp;
 1207         int rc = 0;
 1208         uint16_t error_code;
 1209 
 1210         if (ring->phys_id == (uint16_t)HWRM_NA_SIGNATURE)
 1211                 return 0;
 1212 
 1213         resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1214         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_FREE);
 1215         req.cmpl_ring = htole16(cmpl_ring_id);
 1216         req.ring_type = ring_type;
 1217         req.ring_id = htole16(ring->phys_id);
 1218 
 1219         BNXT_HWRM_LOCK(softc);
 1220         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1221         error_code = le16toh(resp->error_code);
 1222 
 1223         if (rc || error_code) {
 1224                 device_printf(softc->dev, "hwrm_ring_free type %d failed. "
 1225                                 "rc:%x err:%x\n", ring_type, rc, error_code);
 1226                 if (!rc)
 1227                         rc = -EIO;
 1228         }
 1229 
 1230         BNXT_HWRM_UNLOCK(softc);
 1231         return rc;
 1232 }
 1233 
 1234 /*
 1235  * Ring allocation message to the firmware
 1236  */
 1237 int
 1238 bnxt_hwrm_ring_alloc(struct bnxt_softc *softc, uint8_t type,
 1239                      struct bnxt_ring *ring)
 1240 {
 1241         struct hwrm_ring_alloc_input req = {0};
 1242         struct hwrm_ring_alloc_output *resp;
 1243         uint16_t idx = ring->idx;
 1244         struct bnxt_cp_ring *cp_ring;
 1245         int rc;
 1246 
 1247         if (ring->phys_id != (uint16_t)HWRM_NA_SIGNATURE) {
 1248                 device_printf(softc->dev,
 1249                     "Attempt to re-allocate ring %04x\n", ring->phys_id);
 1250                 return EDOOFUS;
 1251         }
 1252 
 1253         resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1254         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_ALLOC);
 1255         req.enables = htole32(0);
 1256         req.fbo = htole32(0);
 1257         req.ring_type = type;
 1258         req.page_tbl_addr = htole64(ring->paddr);
 1259         req.logical_id = htole16(ring->id);
 1260         req.length = htole32(ring->ring_size);
 1261 
 1262         switch (type) {
 1263         case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
 1264                 cp_ring = &softc->tx_cp_rings[idx];
 1265 
 1266                 req.cmpl_ring_id = htole16(cp_ring->ring.phys_id);
 1267                 /* queue_id - what CoS queue the TX ring is associated with */
 1268                 req.queue_id = htole16(softc->q_info[0].id);
 1269 
 1270                 req.stat_ctx_id = htole32(cp_ring->stats_ctx_id);
 1271                 req.enables |= htole32(
 1272                     HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);
 1273                 break;
 1274         case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX:
 1275                 if (!BNXT_CHIP_P5(softc))
 1276                         break;
 1277 
 1278                 cp_ring = &softc->rx_cp_rings[idx];
 1279 
 1280                 req.stat_ctx_id = htole32(cp_ring->stats_ctx_id);
 1281                 req.rx_buf_size = htole16(softc->rx_buf_size);
 1282                 req.enables |= htole32(
 1283                         HWRM_RING_ALLOC_INPUT_ENABLES_RX_BUF_SIZE_VALID |
 1284                         HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);
 1285                 break;
 1286         case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX_AGG:
 1287                 if (!BNXT_CHIP_P5(softc)) {
 1288                         req.ring_type = HWRM_RING_ALLOC_INPUT_RING_TYPE_RX;
 1289                         break;
 1290                 }
 1291 
 1292                 cp_ring = &softc->rx_cp_rings[idx];
 1293 
 1294                 req.rx_ring_id = htole16(softc->rx_rings[idx].phys_id);
 1295                 req.stat_ctx_id = htole32(cp_ring->stats_ctx_id);
 1296                 req.rx_buf_size = htole16(softc->rx_buf_size);
 1297                 req.enables |= htole32(
 1298                             HWRM_RING_ALLOC_INPUT_ENABLES_RX_RING_ID_VALID |
 1299                             HWRM_RING_ALLOC_INPUT_ENABLES_RX_BUF_SIZE_VALID |
 1300                             HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);
 1301                 break;
 1302        case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
 1303                 if (!BNXT_CHIP_P5(softc)) {
 1304                         req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
 1305                         break;
 1306                 }
 1307 
 1308                 req.cq_handle = htole64(ring->id);
 1309                 req.nq_ring_id = htole16(softc->nq_rings[idx].ring.phys_id);
 1310                 req.enables |= htole32(
 1311                         HWRM_RING_ALLOC_INPUT_ENABLES_NQ_RING_ID_VALID);
 1312                 break;
 1313         case HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ:
 1314                 req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
 1315                 break;
 1316         default:
 1317                 printf("hwrm alloc invalid ring type %d\n", type);
 1318                 return -1;
 1319         }
 1320 
 1321         BNXT_HWRM_LOCK(softc);
 1322         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1323         if (rc)
 1324                 goto fail;
 1325 
 1326         ring->phys_id = le16toh(resp->ring_id);
 1327 
 1328 fail:
 1329         BNXT_HWRM_UNLOCK(softc);
 1330         return rc;
 1331 }
 1332 
 1333 int
 1334 bnxt_hwrm_stat_ctx_free(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr)
 1335 {
 1336         struct hwrm_stat_ctx_free_input req = {0};
 1337         int rc = 0;
 1338 
 1339         if (cpr->stats_ctx_id == HWRM_NA_SIGNATURE)
 1340                 return rc;
 1341 
 1342         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_STAT_CTX_FREE);
 1343 
 1344         req.stat_ctx_id = htole16(cpr->stats_ctx_id);
 1345         BNXT_HWRM_LOCK(softc);
 1346         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1347         if (rc)
 1348                 goto fail;
 1349 
 1350 fail:
 1351         BNXT_HWRM_UNLOCK(softc);
 1352 
 1353         return rc;
 1354 }
 1355 
 1356 int
 1357 bnxt_hwrm_stat_ctx_alloc(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr,
 1358     uint64_t paddr)
 1359 {
 1360         struct hwrm_stat_ctx_alloc_input req = {0};
 1361         struct hwrm_stat_ctx_alloc_output *resp;
 1362         int rc = 0;
 1363 
 1364         if (cpr->stats_ctx_id != HWRM_NA_SIGNATURE) {
 1365                 device_printf(softc->dev,
 1366                     "Attempt to re-allocate stats ctx %08x\n",
 1367                     cpr->stats_ctx_id);
 1368                 return EDOOFUS;
 1369         }
 1370 
 1371         resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1372         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_STAT_CTX_ALLOC);
 1373 
 1374         req.update_period_ms = htole32(1000);
 1375         req.stats_dma_addr = htole64(paddr);
 1376         if (BNXT_CHIP_P5(softc))
 1377                 req.stats_dma_length = htole16(sizeof(struct ctx_hw_stats_ext) - 8);
 1378         else
 1379                 req.stats_dma_length = htole16(sizeof(struct ctx_hw_stats));
 1380 
 1381         BNXT_HWRM_LOCK(softc);
 1382         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1383         if (rc)
 1384                 goto fail;
 1385 
 1386         cpr->stats_ctx_id = le32toh(resp->stat_ctx_id);
 1387 
 1388 fail:
 1389         BNXT_HWRM_UNLOCK(softc);
 1390 
 1391         return rc;
 1392 }
 1393 
 1394 int
 1395 bnxt_hwrm_port_qstats(struct bnxt_softc *softc)
 1396 {
 1397         struct hwrm_port_qstats_input req = {0};
 1398         int rc = 0;
 1399 
 1400         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_QSTATS);
 1401 
 1402         req.port_id = htole16(softc->pf.port_id);
 1403         req.rx_stat_host_addr = htole64(softc->hw_rx_port_stats.idi_paddr);
 1404         req.tx_stat_host_addr = htole64(softc->hw_tx_port_stats.idi_paddr);
 1405 
 1406         BNXT_HWRM_LOCK(softc);
 1407         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1408         BNXT_HWRM_UNLOCK(softc);
 1409 
 1410         return rc;
 1411 }
 1412 
 1413 int
 1414 bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt_softc *softc,
 1415     struct bnxt_vnic_info *vnic)
 1416 {
 1417         struct hwrm_cfa_l2_set_rx_mask_input req = {0};
 1418         uint32_t mask = vnic->rx_mask;
 1419 
 1420         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_SET_RX_MASK);
 1421 
 1422         req.vnic_id = htole32(vnic->id);
 1423         req.mask = htole32(mask);
 1424         req.mc_tbl_addr = htole64(vnic->mc_list.idi_paddr);
 1425         req.num_mc_entries = htole32(vnic->mc_list_count);
 1426         return hwrm_send_message(softc, &req, sizeof(req));
 1427 }
 1428 
 1429 int
 1430 bnxt_hwrm_l2_filter_free(struct bnxt_softc *softc, uint64_t filter_id)
 1431 {
 1432         struct hwrm_cfa_l2_filter_free_input    req = {0};
 1433         int rc = 0;
 1434 
 1435         if (filter_id == -1)
 1436                 return rc;
 1437 
 1438         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_FILTER_FREE);
 1439 
 1440         req.l2_filter_id = htole64(filter_id);
 1441 
 1442         BNXT_HWRM_LOCK(softc);
 1443         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1444         if (rc)
 1445                 goto fail;
 1446 
 1447 fail:
 1448         BNXT_HWRM_UNLOCK(softc);
 1449         return (rc);
 1450 }
 1451 
 1452 int
 1453 bnxt_hwrm_free_filter(struct bnxt_softc *softc)
 1454 {
 1455         struct bnxt_vnic_info *vnic = &softc->vnic_info;
 1456         struct bnxt_vlan_tag *tag;
 1457         int rc = 0;
 1458 
 1459         rc = bnxt_hwrm_l2_filter_free(softc, softc->vnic_info.filter_id);
 1460         if (rc)
 1461                 goto end;
 1462 
 1463         SLIST_FOREACH(tag, &vnic->vlan_tags, next) {
 1464                 rc = bnxt_hwrm_l2_filter_free(softc, tag->filter_id);
 1465                 if (rc)
 1466                         goto end;
 1467                 tag->filter_id = -1;
 1468         }
 1469 
 1470 end:
 1471         return rc;
 1472 }
 1473 
 1474 int
 1475 bnxt_hwrm_l2_filter_alloc(struct bnxt_softc *softc, uint16_t vlan_tag,
 1476                 uint64_t *filter_id)
 1477 {
 1478         struct hwrm_cfa_l2_filter_alloc_input   req = {0};
 1479         struct hwrm_cfa_l2_filter_alloc_output  *resp;
 1480         struct bnxt_vnic_info *vnic = &softc->vnic_info;
 1481         uint32_t enables = 0;
 1482         int rc = 0;
 1483 
 1484         if (*filter_id != -1) {
 1485                 device_printf(softc->dev, "Attempt to re-allocate l2 ctx "
 1486                     "filter (fid: 0x%jx)\n", (uintmax_t)*filter_id);
 1487                 return EDOOFUS;
 1488         }
 1489 
 1490         resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1491         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_FILTER_ALLOC);
 1492 
 1493         req.flags = htole32(HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX);
 1494         enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR
 1495             | HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK
 1496             | HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID;
 1497 
 1498         if (vlan_tag != 0xffff) {
 1499                 enables |=
 1500                         HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN |
 1501                         HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK |
 1502                         HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_NUM_VLANS;
 1503                 req.l2_ivlan_mask = 0xffff;
 1504                 req.l2_ivlan = vlan_tag;
 1505                 req.num_vlans = 1;
 1506         }
 1507 
 1508         req.enables = htole32(enables);
 1509         req.dst_id = htole16(vnic->id);
 1510         memcpy(req.l2_addr, if_getlladdr(iflib_get_ifp(softc->ctx)),
 1511             ETHER_ADDR_LEN);
 1512         memset(&req.l2_addr_mask, 0xff, sizeof(req.l2_addr_mask));
 1513 
 1514         BNXT_HWRM_LOCK(softc);
 1515         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1516         if (rc)
 1517                 goto fail;
 1518 
 1519         *filter_id = le64toh(resp->l2_filter_id);
 1520 fail:
 1521         BNXT_HWRM_UNLOCK(softc);
 1522         return (rc);
 1523 }
 1524 
 1525 int
 1526 bnxt_hwrm_set_filter(struct bnxt_softc *softc)
 1527 {
 1528         struct bnxt_vnic_info *vnic = &softc->vnic_info;
 1529         struct bnxt_vlan_tag *tag;
 1530         int rc = 0;
 1531 
 1532         rc = bnxt_hwrm_l2_filter_alloc(softc, 0xffff, &vnic->filter_id);
 1533         if (rc)
 1534                 goto end;
 1535 
 1536         SLIST_FOREACH(tag, &vnic->vlan_tags, next) {
 1537                 rc = bnxt_hwrm_l2_filter_alloc(softc, tag->tag,
 1538                                 &tag->filter_id);
 1539                 if (rc)
 1540                         goto end;
 1541         }
 1542 
 1543 end:
 1544         return rc;
 1545 }
 1546 
 1547 int
 1548 bnxt_hwrm_rss_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic,
 1549     uint32_t hash_type)
 1550 {
 1551         struct hwrm_vnic_rss_cfg_input  req = {0};
 1552 
 1553         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_RSS_CFG);
 1554 
 1555         req.hash_type = htole32(hash_type);
 1556         req.ring_grp_tbl_addr = htole64(vnic->rss_grp_tbl.idi_paddr);
 1557         req.hash_key_tbl_addr = htole64(vnic->rss_hash_key_tbl.idi_paddr);
 1558         req.rss_ctx_idx = htole16(vnic->rss_id);
 1559         req.hash_mode_flags = HWRM_FUNC_SPD_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
 1560         if (BNXT_CHIP_P5(softc)) {
 1561                 req.vnic_id = htole16(vnic->id);
 1562                 req.ring_table_pair_index = 0x0;
 1563         }
 1564 
 1565         return hwrm_send_message(softc, &req, sizeof(req));
 1566 }
 1567 
 1568 int
 1569 bnxt_hwrm_reserve_pf_rings(struct bnxt_softc *softc)
 1570 {
 1571         struct hwrm_func_cfg_input req = {0};
 1572 
 1573         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG);
 1574 
 1575         req.fid = htole16(0xffff);
 1576         req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS);
 1577         req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS);
 1578         req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS);
 1579         req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS);
 1580         req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS);
 1581         req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_MSIX);
 1582         req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS);
 1583         req.num_msix = htole16(BNXT_MAX_NUM_QUEUES);
 1584         req.num_rsscos_ctxs = htole16(0x8);
 1585         req.num_cmpl_rings = htole16(BNXT_MAX_NUM_QUEUES * 2);
 1586         req.num_tx_rings = htole16(BNXT_MAX_NUM_QUEUES);
 1587         req.num_rx_rings = htole16(BNXT_MAX_NUM_QUEUES);
 1588         req.num_vnics = htole16(BNXT_MAX_NUM_QUEUES);
 1589         req.num_stat_ctxs = htole16(BNXT_MAX_NUM_QUEUES * 2);
 1590 
 1591         return hwrm_send_message(softc, &req, sizeof(req));
 1592 }
 1593 
 1594 int
 1595 bnxt_cfg_async_cr(struct bnxt_softc *softc)
 1596 {
 1597         int rc = 0;
 1598         struct hwrm_func_cfg_input req = {0};
 1599 
 1600         if (!BNXT_PF(softc))
 1601                 return 0;
 1602 
 1603         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG);
 1604 
 1605         req.fid = htole16(0xffff);
 1606         req.enables = htole32(HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
 1607         if (BNXT_CHIP_P5(softc))
 1608                 req.async_event_cr = htole16(softc->nq_rings[0].ring.phys_id);
 1609         else
 1610                 req.async_event_cr = htole16(softc->def_cp_ring.ring.phys_id);
 1611 
 1612         rc = hwrm_send_message(softc, &req, sizeof(req));
 1613 
 1614         return rc;
 1615 }
 1616 
 1617 void
 1618 bnxt_validate_hw_lro_settings(struct bnxt_softc *softc)
 1619 {
 1620         softc->hw_lro.enable = min(softc->hw_lro.enable, 1);
 1621 
 1622         softc->hw_lro.is_mode_gro = min(softc->hw_lro.is_mode_gro, 1);
 1623 
 1624         softc->hw_lro.max_agg_segs = min(softc->hw_lro.max_agg_segs,
 1625                 HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX);
 1626 
 1627         softc->hw_lro.max_aggs = min(softc->hw_lro.max_aggs,
 1628                 HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX);
 1629 
 1630         softc->hw_lro.min_agg_len = min(softc->hw_lro.min_agg_len, BNXT_MAX_MTU);
 1631 }
 1632 
 1633 int
 1634 bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc)
 1635 {
 1636         struct hwrm_vnic_tpa_cfg_input req = {0};
 1637         uint32_t flags;
 1638 
 1639         if (softc->vnic_info.id == (uint16_t) HWRM_NA_SIGNATURE) {
 1640                 return 0;
 1641         }
 1642 
 1643         if (!(softc->flags & BNXT_FLAG_TPA))
 1644                 return 0;
 1645 
 1646         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_TPA_CFG);
 1647 
 1648         if (softc->hw_lro.enable) {
 1649                 flags = HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA |
 1650                         HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA |
 1651                         HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN |
 1652                         HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ;
 1653 
 1654                 if (softc->hw_lro.is_mode_gro)
 1655                         flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO;
 1656                 else
 1657                         flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE;
 1658 
 1659                 req.flags = htole32(flags);
 1660 
 1661                 req.enables = htole32(HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS |
 1662                                 HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS |
 1663                                 HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN);
 1664 
 1665                 req.max_agg_segs = htole16(softc->hw_lro.max_agg_segs);
 1666                 req.max_aggs = htole16(softc->hw_lro.max_aggs);
 1667                 req.min_agg_len = htole32(softc->hw_lro.min_agg_len);
 1668         }
 1669 
 1670         req.vnic_id = htole16(softc->vnic_info.id);
 1671 
 1672         return hwrm_send_message(softc, &req, sizeof(req));
 1673 }
 1674 
 1675 int
 1676 bnxt_hwrm_nvm_find_dir_entry(struct bnxt_softc *softc, uint16_t type,
 1677     uint16_t *ordinal, uint16_t ext, uint16_t *index, bool use_index,
 1678     uint8_t search_opt, uint32_t *data_length, uint32_t *item_length,
 1679     uint32_t *fw_ver)
 1680 {
 1681         struct hwrm_nvm_find_dir_entry_input req = {0};
 1682         struct hwrm_nvm_find_dir_entry_output *resp =
 1683             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1684         int     rc = 0;
 1685         uint32_t old_timeo;
 1686 
 1687         MPASS(ordinal);
 1688 
 1689         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_FIND_DIR_ENTRY);
 1690         if (use_index) {
 1691                 req.enables = htole32(
 1692                     HWRM_NVM_FIND_DIR_ENTRY_INPUT_ENABLES_DIR_IDX_VALID);
 1693                 req.dir_idx = htole16(*index);
 1694         }
 1695         req.dir_type = htole16(type);
 1696         req.dir_ordinal = htole16(*ordinal);
 1697         req.dir_ext = htole16(ext);
 1698         req.opt_ordinal = search_opt;
 1699 
 1700         BNXT_HWRM_LOCK(softc);
 1701         old_timeo = softc->hwrm_cmd_timeo;
 1702         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 1703         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1704         softc->hwrm_cmd_timeo = old_timeo;
 1705         if (rc)
 1706                 goto exit;
 1707 
 1708         if (item_length)
 1709                 *item_length = le32toh(resp->dir_item_length);
 1710         if (data_length)
 1711                 *data_length = le32toh(resp->dir_data_length);
 1712         if (fw_ver)
 1713                 *fw_ver = le32toh(resp->fw_ver);
 1714         *ordinal = le16toh(resp->dir_ordinal);
 1715         if (index)
 1716                 *index = le16toh(resp->dir_idx);
 1717 
 1718 exit:
 1719         BNXT_HWRM_UNLOCK(softc);
 1720         return (rc);
 1721 }
 1722 
 1723 int
 1724 bnxt_hwrm_nvm_read(struct bnxt_softc *softc, uint16_t index, uint32_t offset,
 1725     uint32_t length, struct iflib_dma_info *data)
 1726 {
 1727         struct hwrm_nvm_read_input req = {0};
 1728         int rc;
 1729         uint32_t old_timeo;
 1730 
 1731         if (length > data->idi_size) {
 1732                 rc = EINVAL;
 1733                 goto exit;
 1734         }
 1735         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_READ);
 1736         req.host_dest_addr = htole64(data->idi_paddr);
 1737         req.dir_idx = htole16(index);
 1738         req.offset = htole32(offset);
 1739         req.len = htole32(length);
 1740         BNXT_HWRM_LOCK(softc);
 1741         old_timeo = softc->hwrm_cmd_timeo;
 1742         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 1743         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1744         softc->hwrm_cmd_timeo = old_timeo;
 1745         BNXT_HWRM_UNLOCK(softc);
 1746         if (rc)
 1747                 goto exit;
 1748         bus_dmamap_sync(data->idi_tag, data->idi_map, BUS_DMASYNC_POSTREAD);
 1749 
 1750         goto exit;
 1751 
 1752 exit:
 1753         return rc;
 1754 }
 1755 
 1756 int
 1757 bnxt_hwrm_nvm_modify(struct bnxt_softc *softc, uint16_t index, uint32_t offset,
 1758     void *data, bool cpyin, uint32_t length)
 1759 {
 1760         struct hwrm_nvm_modify_input req = {0};
 1761         struct iflib_dma_info dma_data;
 1762         int rc;
 1763         uint32_t old_timeo;
 1764 
 1765         if (length == 0 || !data)
 1766                 return EINVAL;
 1767         rc = iflib_dma_alloc(softc->ctx, length, &dma_data,
 1768             BUS_DMA_NOWAIT);
 1769         if (rc)
 1770                 return ENOMEM;
 1771         if (cpyin) {
 1772                 rc = copyin(data, dma_data.idi_vaddr, length);
 1773                 if (rc)
 1774                         goto exit;
 1775         }
 1776         else
 1777                 memcpy(dma_data.idi_vaddr, data, length);
 1778         bus_dmamap_sync(dma_data.idi_tag, dma_data.idi_map,
 1779             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1780 
 1781         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_MODIFY);
 1782         req.host_src_addr = htole64(dma_data.idi_paddr);
 1783         req.dir_idx = htole16(index);
 1784         req.offset = htole32(offset);
 1785         req.len = htole32(length);
 1786         BNXT_HWRM_LOCK(softc);
 1787         old_timeo = softc->hwrm_cmd_timeo;
 1788         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 1789         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1790         softc->hwrm_cmd_timeo = old_timeo;
 1791         BNXT_HWRM_UNLOCK(softc);
 1792 
 1793 exit:
 1794         iflib_dma_free(&dma_data);
 1795         return rc;
 1796 }
 1797 
 1798 int
 1799 bnxt_hwrm_fw_reset(struct bnxt_softc *softc, uint8_t processor,
 1800     uint8_t *selfreset)
 1801 {
 1802         struct hwrm_fw_reset_input req = {0};
 1803         struct hwrm_fw_reset_output *resp =
 1804             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1805         int rc;
 1806 
 1807         MPASS(selfreset);
 1808 
 1809         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_RESET);
 1810         req.embedded_proc_type = processor;
 1811         req.selfrst_status = *selfreset;
 1812 
 1813         BNXT_HWRM_LOCK(softc);
 1814         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1815         if (rc)
 1816                 goto exit;
 1817         *selfreset = resp->selfrst_status;
 1818 
 1819 exit:
 1820         BNXT_HWRM_UNLOCK(softc);
 1821         return rc;
 1822 }
 1823 
 1824 int
 1825 bnxt_hwrm_fw_qstatus(struct bnxt_softc *softc, uint8_t type, uint8_t *selfreset)
 1826 {
 1827         struct hwrm_fw_qstatus_input req = {0};
 1828         struct hwrm_fw_qstatus_output *resp =
 1829             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1830         int rc;
 1831 
 1832         MPASS(selfreset);
 1833 
 1834         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_QSTATUS);
 1835         req.embedded_proc_type = type;
 1836 
 1837         BNXT_HWRM_LOCK(softc);
 1838         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1839         if (rc)
 1840                 goto exit;
 1841         *selfreset = resp->selfrst_status;
 1842 
 1843 exit:
 1844         BNXT_HWRM_UNLOCK(softc);
 1845         return rc;
 1846 }
 1847 
 1848 int
 1849 bnxt_hwrm_nvm_write(struct bnxt_softc *softc, void *data, bool cpyin,
 1850     uint16_t type, uint16_t ordinal, uint16_t ext, uint16_t attr,
 1851     uint16_t option, uint32_t data_length, bool keep, uint32_t *item_length,
 1852     uint16_t *index)
 1853 {
 1854         struct hwrm_nvm_write_input req = {0};
 1855         struct hwrm_nvm_write_output *resp =
 1856             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1857         struct iflib_dma_info dma_data;
 1858         int rc;
 1859         uint32_t old_timeo;
 1860 
 1861         if (data_length) {
 1862                 rc = iflib_dma_alloc(softc->ctx, data_length, &dma_data,
 1863                     BUS_DMA_NOWAIT);
 1864                 if (rc)
 1865                         return ENOMEM;
 1866                 if (cpyin) {
 1867                         rc = copyin(data, dma_data.idi_vaddr, data_length);
 1868                         if (rc)
 1869                                 goto early_exit;
 1870                 }
 1871                 else
 1872                         memcpy(dma_data.idi_vaddr, data, data_length);
 1873                 bus_dmamap_sync(dma_data.idi_tag, dma_data.idi_map,
 1874                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1875         }
 1876         else
 1877                 dma_data.idi_paddr = 0;
 1878 
 1879         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_WRITE);
 1880 
 1881         req.host_src_addr = htole64(dma_data.idi_paddr);
 1882         req.dir_type = htole16(type);
 1883         req.dir_ordinal = htole16(ordinal);
 1884         req.dir_ext = htole16(ext);
 1885         req.dir_attr = htole16(attr);
 1886         req.dir_data_length = htole32(data_length);
 1887         req.option = htole16(option);
 1888         if (keep) {
 1889                 req.flags =
 1890                     htole16(HWRM_NVM_WRITE_INPUT_FLAGS_KEEP_ORIG_ACTIVE_IMG);
 1891         }
 1892         if (item_length)
 1893                 req.dir_item_length = htole32(*item_length);
 1894 
 1895         BNXT_HWRM_LOCK(softc);
 1896         old_timeo = softc->hwrm_cmd_timeo;
 1897         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 1898         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1899         softc->hwrm_cmd_timeo = old_timeo;
 1900         if (rc)
 1901                 goto exit;
 1902         if (item_length)
 1903                 *item_length = le32toh(resp->dir_item_length);
 1904         if (index)
 1905                 *index = le16toh(resp->dir_idx);
 1906 
 1907 exit:
 1908         BNXT_HWRM_UNLOCK(softc);
 1909 early_exit:
 1910         if (data_length)
 1911                 iflib_dma_free(&dma_data);
 1912         return rc;
 1913 }
 1914 
 1915 int
 1916 bnxt_hwrm_nvm_erase_dir_entry(struct bnxt_softc *softc, uint16_t index)
 1917 {
 1918         struct hwrm_nvm_erase_dir_entry_input req = {0};
 1919         uint32_t old_timeo;
 1920         int rc;
 1921 
 1922         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_ERASE_DIR_ENTRY);
 1923         req.dir_idx = htole16(index);
 1924         BNXT_HWRM_LOCK(softc);
 1925         old_timeo = softc->hwrm_cmd_timeo;
 1926         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 1927         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1928         softc->hwrm_cmd_timeo = old_timeo;
 1929         BNXT_HWRM_UNLOCK(softc);
 1930         return rc;
 1931 }
 1932 
 1933 int
 1934 bnxt_hwrm_nvm_get_dir_info(struct bnxt_softc *softc, uint32_t *entries,
 1935     uint32_t *entry_length)
 1936 {
 1937         struct hwrm_nvm_get_dir_info_input req = {0};
 1938         struct hwrm_nvm_get_dir_info_output *resp =
 1939             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 1940         int rc;
 1941         uint32_t old_timeo;
 1942 
 1943         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_GET_DIR_INFO);
 1944 
 1945         BNXT_HWRM_LOCK(softc);
 1946         old_timeo = softc->hwrm_cmd_timeo;
 1947         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 1948         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1949         softc->hwrm_cmd_timeo = old_timeo;
 1950         if (rc)
 1951                 goto exit;
 1952 
 1953         if (entries)
 1954                 *entries = le32toh(resp->entries);
 1955         if (entry_length)
 1956                 *entry_length = le32toh(resp->entry_length);
 1957 
 1958 exit:
 1959         BNXT_HWRM_UNLOCK(softc);
 1960         return rc;
 1961 }
 1962 
 1963 int
 1964 bnxt_hwrm_nvm_get_dir_entries(struct bnxt_softc *softc, uint32_t *entries,
 1965     uint32_t *entry_length, struct iflib_dma_info *dma_data)
 1966 {
 1967         struct hwrm_nvm_get_dir_entries_input req = {0};
 1968         uint32_t ent;
 1969         uint32_t ent_len;
 1970         int rc;
 1971         uint32_t old_timeo;
 1972 
 1973         if (!entries)
 1974                 entries = &ent;
 1975         if (!entry_length)
 1976                 entry_length = &ent_len;
 1977 
 1978         rc = bnxt_hwrm_nvm_get_dir_info(softc, entries, entry_length);
 1979         if (rc)
 1980                 goto exit;
 1981         if (*entries * *entry_length > dma_data->idi_size) {
 1982                 rc = EINVAL;
 1983                 goto exit;
 1984         }
 1985 
 1986         /*
 1987          * TODO: There's a race condition here that could blow up DMA memory...
 1988          *       we need to allocate the max size, not the currently in use
 1989          *       size.  The command should totally have a max size here.
 1990          */
 1991         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_GET_DIR_ENTRIES);
 1992         req.host_dest_addr = htole64(dma_data->idi_paddr);
 1993         BNXT_HWRM_LOCK(softc);
 1994         old_timeo = softc->hwrm_cmd_timeo;
 1995         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 1996         rc = _hwrm_send_message(softc, &req, sizeof(req));
 1997         softc->hwrm_cmd_timeo = old_timeo;
 1998         BNXT_HWRM_UNLOCK(softc);
 1999         if (rc)
 2000                 goto exit;
 2001         bus_dmamap_sync(dma_data->idi_tag, dma_data->idi_map,
 2002             BUS_DMASYNC_POSTWRITE);
 2003 
 2004 exit:
 2005         return rc;
 2006 }
 2007 
 2008 int
 2009 bnxt_hwrm_nvm_get_dev_info(struct bnxt_softc *softc, uint16_t *mfg_id,
 2010     uint16_t *device_id, uint32_t *sector_size, uint32_t *nvram_size,
 2011     uint32_t *reserved_size, uint32_t *available_size)
 2012 {
 2013         struct hwrm_nvm_get_dev_info_input req = {0};
 2014         struct hwrm_nvm_get_dev_info_output *resp =
 2015             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 2016         int rc;
 2017         uint32_t old_timeo;
 2018 
 2019         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_GET_DEV_INFO);
 2020 
 2021         BNXT_HWRM_LOCK(softc);
 2022         old_timeo = softc->hwrm_cmd_timeo;
 2023         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 2024         rc = _hwrm_send_message(softc, &req, sizeof(req));
 2025         softc->hwrm_cmd_timeo = old_timeo;
 2026         if (rc)
 2027                 goto exit;
 2028 
 2029         if (mfg_id)
 2030                 *mfg_id = le16toh(resp->manufacturer_id);
 2031         if (device_id)
 2032                 *device_id = le16toh(resp->device_id);
 2033         if (sector_size)
 2034                 *sector_size = le32toh(resp->sector_size);
 2035         if (nvram_size)
 2036                 *nvram_size = le32toh(resp->nvram_size);
 2037         if (reserved_size)
 2038                 *reserved_size = le32toh(resp->reserved_size);
 2039         if (available_size)
 2040                 *available_size = le32toh(resp->available_size);
 2041 
 2042 exit:
 2043         BNXT_HWRM_UNLOCK(softc);
 2044         return rc;
 2045 }
 2046 
 2047 int
 2048 bnxt_hwrm_nvm_install_update(struct bnxt_softc *softc,
 2049     uint32_t install_type, uint64_t *installed_items, uint8_t *result,
 2050     uint8_t *problem_item, uint8_t *reset_required)
 2051 {
 2052         struct hwrm_nvm_install_update_input req = {0};
 2053         struct hwrm_nvm_install_update_output *resp =
 2054             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 2055         int rc;
 2056         uint32_t old_timeo;
 2057 
 2058         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_INSTALL_UPDATE);
 2059         req.install_type = htole32(install_type);
 2060 
 2061         BNXT_HWRM_LOCK(softc);
 2062         old_timeo = softc->hwrm_cmd_timeo;
 2063         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 2064         rc = _hwrm_send_message(softc, &req, sizeof(req));
 2065         softc->hwrm_cmd_timeo = old_timeo;
 2066         if (rc)
 2067                 goto exit;
 2068 
 2069         if (installed_items)
 2070                 *installed_items = le32toh(resp->installed_items);
 2071         if (result)
 2072                 *result = resp->result;
 2073         if (problem_item)
 2074                 *problem_item = resp->problem_item;
 2075         if (reset_required)
 2076                 *reset_required = resp->reset_required;
 2077 
 2078 exit:
 2079         BNXT_HWRM_UNLOCK(softc);
 2080         return rc;
 2081 }
 2082 
 2083 int
 2084 bnxt_hwrm_nvm_verify_update(struct bnxt_softc *softc, uint16_t type,
 2085     uint16_t ordinal, uint16_t ext)
 2086 {
 2087         struct hwrm_nvm_verify_update_input req = {0};
 2088         uint32_t old_timeo;
 2089         int rc;
 2090 
 2091         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_VERIFY_UPDATE);
 2092 
 2093         req.dir_type = htole16(type);
 2094         req.dir_ordinal = htole16(ordinal);
 2095         req.dir_ext = htole16(ext);
 2096 
 2097         BNXT_HWRM_LOCK(softc);
 2098         old_timeo = softc->hwrm_cmd_timeo;
 2099         softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
 2100         rc = _hwrm_send_message(softc, &req, sizeof(req));
 2101         softc->hwrm_cmd_timeo = old_timeo;
 2102         BNXT_HWRM_UNLOCK(softc);
 2103         return rc;
 2104 }
 2105 
 2106 int
 2107 bnxt_hwrm_fw_get_time(struct bnxt_softc *softc, uint16_t *year, uint8_t *month,
 2108     uint8_t *day, uint8_t *hour, uint8_t *minute, uint8_t *second,
 2109     uint16_t *millisecond, uint16_t *zone)
 2110 {
 2111         struct hwrm_fw_get_time_input req = {0};
 2112         struct hwrm_fw_get_time_output *resp =
 2113             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 2114         int rc;
 2115 
 2116         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_GET_TIME);
 2117 
 2118         BNXT_HWRM_LOCK(softc);
 2119         rc = _hwrm_send_message(softc, &req, sizeof(req));
 2120         if (rc)
 2121                 goto exit;
 2122 
 2123         if (year)
 2124                 *year = le16toh(resp->year);
 2125         if (month)
 2126                 *month = resp->month;
 2127         if (day)
 2128                 *day = resp->day;
 2129         if (hour)
 2130                 *hour = resp->hour;
 2131         if (minute)
 2132                 *minute = resp->minute;
 2133         if (second)
 2134                 *second = resp->second;
 2135         if (millisecond)
 2136                 *millisecond = le16toh(resp->millisecond);
 2137         if (zone)
 2138                 *zone = le16toh(resp->zone);
 2139 
 2140 exit:
 2141         BNXT_HWRM_UNLOCK(softc);
 2142         return rc;
 2143 }
 2144 
 2145 int
 2146 bnxt_hwrm_fw_set_time(struct bnxt_softc *softc, uint16_t year, uint8_t month,
 2147     uint8_t day, uint8_t hour, uint8_t minute, uint8_t second,
 2148     uint16_t millisecond, uint16_t zone)
 2149 {
 2150         struct hwrm_fw_set_time_input req = {0};
 2151 
 2152         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_SET_TIME);
 2153 
 2154         req.year = htole16(year);
 2155         req.month = month;
 2156         req.day = day;
 2157         req.hour = hour;
 2158         req.minute = minute;
 2159         req.second = second;
 2160         req.millisecond = htole16(millisecond);
 2161         req.zone = htole16(zone);
 2162         return hwrm_send_message(softc, &req, sizeof(req));
 2163 }
 2164 
 2165 int
 2166 bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc)
 2167 {
 2168         struct bnxt_link_info *link_info = &softc->link_info;
 2169         struct hwrm_port_phy_qcfg_input req = {0};
 2170         struct hwrm_port_phy_qcfg_output *resp =
 2171             (void *)softc->hwrm_cmd_resp.idi_vaddr;
 2172         int rc = 0;
 2173 
 2174         BNXT_HWRM_LOCK(softc);
 2175         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_QCFG);
 2176 
 2177         rc = _hwrm_send_message(softc, &req, sizeof(req));
 2178         if (rc)
 2179                 goto exit;
 2180 
 2181         link_info->phy_link_status = resp->link;
 2182         link_info->duplex =  resp->duplex_cfg;
 2183         link_info->auto_mode = resp->auto_mode;
 2184 
 2185         /*
 2186          * When AUTO_PAUSE_AUTONEG_PAUSE bit is set to 1,
 2187          * the advertisement of pause is enabled.
 2188          * 1. When the auto_mode is not set to none and this flag is set to 1,
 2189          *    then the auto_pause bits on this port are being advertised and
 2190          *    autoneg pause results are being interpreted.
 2191          * 2. When the auto_mode is not set to none and this flag is set to 0,
 2192          *    the pause is forced as indicated in force_pause, and also
 2193          *    advertised as auto_pause bits, but the autoneg results are not
 2194          *    interpreted since the pause configuration is being forced.
 2195          * 3. When the auto_mode is set to none and this flag is set to 1,
 2196          *    auto_pause bits should be ignored and should be set to 0.
 2197          */
 2198 
 2199         link_info->flow_ctrl.autoneg = false;
 2200         link_info->flow_ctrl.tx = false;
 2201         link_info->flow_ctrl.rx = false;
 2202 
 2203         if ((resp->auto_mode) &&
 2204             (resp->auto_pause & BNXT_AUTO_PAUSE_AUTONEG_PAUSE)) {
 2205                         link_info->flow_ctrl.autoneg = true;
 2206         }
 2207 
 2208         if (link_info->flow_ctrl.autoneg) {
 2209                 if (resp->auto_pause & BNXT_PAUSE_TX)
 2210                         link_info->flow_ctrl.tx = true;
 2211                 if (resp->auto_pause & BNXT_PAUSE_RX)
 2212                         link_info->flow_ctrl.rx = true;
 2213         } else {
 2214                 if (resp->force_pause & BNXT_PAUSE_TX)
 2215                         link_info->flow_ctrl.tx = true;
 2216                 if (resp->force_pause & BNXT_PAUSE_RX)
 2217                         link_info->flow_ctrl.rx = true;
 2218         }
 2219 
 2220         link_info->duplex_setting = resp->duplex_cfg;
 2221         if (link_info->phy_link_status == HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK)
 2222                 link_info->link_speed = le16toh(resp->link_speed);
 2223         else
 2224                 link_info->link_speed = 0;
 2225         link_info->force_link_speed = le16toh(resp->force_link_speed);
 2226         link_info->auto_link_speed = le16toh(resp->auto_link_speed);
 2227         link_info->support_speeds = le16toh(resp->support_speeds);
 2228         link_info->auto_link_speeds = le16toh(resp->auto_link_speed_mask);
 2229         link_info->preemphasis = le32toh(resp->preemphasis);
 2230         link_info->phy_ver[0] = resp->phy_maj;
 2231         link_info->phy_ver[1] = resp->phy_min;
 2232         link_info->phy_ver[2] = resp->phy_bld;
 2233         snprintf(softc->ver_info->phy_ver, sizeof(softc->ver_info->phy_ver),
 2234             "%d.%d.%d", link_info->phy_ver[0], link_info->phy_ver[1],
 2235             link_info->phy_ver[2]);
 2236         strlcpy(softc->ver_info->phy_vendor, resp->phy_vendor_name,
 2237             BNXT_NAME_SIZE);
 2238         strlcpy(softc->ver_info->phy_partnumber, resp->phy_vendor_partnumber,
 2239             BNXT_NAME_SIZE);
 2240         link_info->media_type = resp->media_type;
 2241         link_info->phy_type = resp->phy_type;
 2242         link_info->transceiver = resp->xcvr_pkg_type;
 2243         link_info->phy_addr = resp->eee_config_phy_addr &
 2244             HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_MASK;
 2245 
 2246 exit:
 2247         BNXT_HWRM_UNLOCK(softc);
 2248         return rc;
 2249 }
 2250 
 2251 uint16_t
 2252 bnxt_hwrm_get_wol_fltrs(struct bnxt_softc *softc, uint16_t handle)
 2253 {
 2254         struct hwrm_wol_filter_qcfg_input req = {0};
 2255         struct hwrm_wol_filter_qcfg_output *resp =
 2256                         (void *)softc->hwrm_cmd_resp.idi_vaddr;
 2257         uint16_t next_handle = 0;
 2258         int rc;
 2259 
 2260         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_WOL_FILTER_QCFG);
 2261         req.port_id = htole16(softc->pf.port_id);
 2262         req.handle = htole16(handle);
 2263         rc = hwrm_send_message(softc, &req, sizeof(req));
 2264         if (!rc) {
 2265                 next_handle = le16toh(resp->next_handle);
 2266                 if (next_handle != 0) {
 2267                         if (resp->wol_type ==
 2268                                 HWRM_WOL_FILTER_ALLOC_INPUT_WOL_TYPE_MAGICPKT) {
 2269                                 softc->wol = 1;
 2270                                 softc->wol_filter_id = resp->wol_filter_id;
 2271                         }
 2272                 }
 2273         }
 2274         return next_handle;
 2275 }
 2276 
 2277 int
 2278 bnxt_hwrm_alloc_wol_fltr(struct bnxt_softc *softc)
 2279 {
 2280         struct hwrm_wol_filter_alloc_input req = {0};
 2281         struct hwrm_wol_filter_alloc_output *resp =
 2282                 (void *)softc->hwrm_cmd_resp.idi_vaddr;
 2283         int rc;
 2284 
 2285         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_WOL_FILTER_ALLOC);
 2286         req.port_id = htole16(softc->pf.port_id);
 2287         req.wol_type = HWRM_WOL_FILTER_ALLOC_INPUT_WOL_TYPE_MAGICPKT;
 2288         req.enables =
 2289                 htole32(HWRM_WOL_FILTER_ALLOC_INPUT_ENABLES_MAC_ADDRESS);
 2290         memcpy(req.mac_address, softc->func.mac_addr, ETHER_ADDR_LEN);
 2291         rc = hwrm_send_message(softc, &req, sizeof(req));
 2292         if (!rc)
 2293                 softc->wol_filter_id = resp->wol_filter_id;
 2294 
 2295         return rc;
 2296 }
 2297 
 2298 int
 2299 bnxt_hwrm_free_wol_fltr(struct bnxt_softc *softc)
 2300 {
 2301         struct hwrm_wol_filter_free_input req = {0};
 2302 
 2303         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_WOL_FILTER_FREE);
 2304         req.port_id = htole16(softc->pf.port_id);
 2305         req.enables =
 2306                 htole32(HWRM_WOL_FILTER_FREE_INPUT_ENABLES_WOL_FILTER_ID);
 2307         req.wol_filter_id = softc->wol_filter_id;
 2308         return hwrm_send_message(softc, &req, sizeof(req));
 2309 }
 2310 
 2311 static void bnxt_hwrm_set_coal_params(struct bnxt_softc *softc, uint32_t max_frames,
 2312         uint32_t buf_tmrs, uint16_t flags,
 2313         struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req)
 2314 {
 2315         req->flags = htole16(flags);
 2316         req->num_cmpl_dma_aggr = htole16((uint16_t)max_frames);
 2317         req->num_cmpl_dma_aggr_during_int = htole16(max_frames >> 16);
 2318         req->cmpl_aggr_dma_tmr = htole16((uint16_t)buf_tmrs);
 2319         req->cmpl_aggr_dma_tmr_during_int = htole16(buf_tmrs >> 16);
 2320         /* Minimum time between 2 interrupts set to buf_tmr x 2 */
 2321         req->int_lat_tmr_min = htole16((uint16_t)buf_tmrs * 2);
 2322         req->int_lat_tmr_max = htole16((uint16_t)buf_tmrs * 4);
 2323         req->num_cmpl_aggr_int = htole16((uint16_t)max_frames * 4);
 2324 }
 2325 
 2326 int bnxt_hwrm_set_coal(struct bnxt_softc *softc)
 2327 {
 2328         int i, rc = 0;
 2329         struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0},
 2330                                                            req_tx = {0}, *req;
 2331         uint16_t max_buf, max_buf_irq;
 2332         uint16_t buf_tmr, buf_tmr_irq;
 2333         uint32_t flags;
 2334 
 2335         bnxt_hwrm_cmd_hdr_init(softc, &req_rx,
 2336                                HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
 2337         bnxt_hwrm_cmd_hdr_init(softc, &req_tx,
 2338                                HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
 2339 
 2340         /* Each rx completion (2 records) should be DMAed immediately.
 2341          * DMA 1/4 of the completion buffers at a time.
 2342          */
 2343         max_buf = min_t(uint16_t, softc->rx_coal_frames / 4, 2);
 2344         /* max_buf must not be zero */
 2345         max_buf = clamp_t(uint16_t, max_buf, 1, 63);
 2346         max_buf_irq = clamp_t(uint16_t, softc->rx_coal_frames_irq, 1, 63);
 2347         buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs);
 2348         /* buf timer set to 1/4 of interrupt timer */
 2349         buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
 2350         buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs_irq);
 2351         buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
 2352 
 2353         flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
 2354 
 2355         /* RING_IDLE generates more IRQs for lower latency.  Enable it only
 2356          * if coal_usecs is less than 25 us.
 2357          */
 2358         if (softc->rx_coal_usecs < 25)
 2359                 flags |= HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE;
 2360 
 2361         bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
 2362                                   buf_tmr_irq << 16 | buf_tmr, flags, &req_rx);
 2363 
 2364         /* max_buf must not be zero */
 2365         max_buf = clamp_t(uint16_t, softc->tx_coal_frames, 1, 63);
 2366         max_buf_irq = clamp_t(uint16_t, softc->tx_coal_frames_irq, 1, 63);
 2367         buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs);
 2368         /* buf timer set to 1/4 of interrupt timer */
 2369         buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
 2370         buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs_irq);
 2371         buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
 2372         flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
 2373         bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
 2374                                   buf_tmr_irq << 16 | buf_tmr, flags, &req_tx);
 2375 
 2376         for (i = 0; i < softc->nrxqsets; i++) {
 2377 
 2378                 req = &req_rx;
 2379                 /*
 2380                  * TBD:
 2381                  *      Check if Tx also needs to be done
 2382                  *      So far, Tx processing has been done in softirq contest
 2383                  *
 2384                  * req = &req_tx;
 2385                  */
 2386                 req->ring_id = htole16(softc->grp_info[i].cp_ring_id);
 2387 
 2388                 rc = hwrm_send_message(softc, req, sizeof(*req));
 2389                 if (rc)
 2390                         break;
 2391         }
 2392         return rc;
 2393 }
 2394 
 2395 int bnxt_hwrm_func_rgtr_async_events(struct bnxt_softc *softc, unsigned long *bmap,
 2396                                      int bmap_size)
 2397 {
 2398         struct hwrm_func_drv_rgtr_input req = {0};
 2399         bitstr_t *async_events_bmap;
 2400         uint32_t *events;
 2401         int i;
 2402 
 2403 #define BNXT_MAX_NUM_ASYNC_EVENTS 256
 2404         async_events_bmap = bit_alloc(BNXT_MAX_NUM_ASYNC_EVENTS, M_DEVBUF,
 2405                         M_WAITOK|M_ZERO);
 2406         events = (uint32_t *)async_events_bmap;
 2407 
 2408         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_DRV_RGTR);
 2409 
 2410         req.enables =
 2411                 htole32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD);
 2412 
 2413         memset(async_events_bmap, 0, sizeof(BNXT_MAX_NUM_ASYNC_EVENTS / 8));
 2414 
 2415         bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE);
 2416         bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD);
 2417         bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED);
 2418         bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE);
 2419         bit_set(async_events_bmap, HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE);
 2420 
 2421         if (bmap && bmap_size) {
 2422                 for (i = 0; i < bmap_size; i++) {
 2423                         if (bit_test(bmap, i))
 2424                                 bit_set(async_events_bmap, i);
 2425                 }
 2426         }
 2427 
 2428         for (i = 0; i < 8; i++)
 2429                 req.async_event_fwd[i] |= htole32(events[i]);
 2430 
 2431         free(async_events_bmap, M_DEVBUF);
 2432 
 2433         return hwrm_send_message(softc, &req, sizeof(req));
 2434 }
 2435 
 2436 void bnxt_hwrm_ring_info_get(struct bnxt_softc *softc, uint8_t ring_type,
 2437                                        uint32_t ring_id,  uint32_t *prod, uint32_t *cons)
 2438 {
 2439         hwrm_dbg_ring_info_get_input_t req = {0};
 2440         hwrm_dbg_ring_info_get_output_t *resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
 2441         int rc = 0;
 2442 
 2443         *prod = *cons = 0xffffffff;
 2444         bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_DBG_RING_INFO_GET);
 2445         req.ring_type = le32toh(ring_type);
 2446         req.fw_ring_id = le32toh(ring_id);
 2447         rc = hwrm_send_message(softc, &req, sizeof(req));
 2448         if (!rc) {
 2449                 *prod = resp->producer_index;
 2450                 *cons = resp->consumer_index;
 2451         }
 2452 
 2453         return;
 2454 }

Cache object: a928cf2dc783604a590a5394bc85551e


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