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 #include <sys/endian.h> 31 #include <linux/pci.h> 32 33 #include "bnxt.h" 34 #include "bnxt_hwrm.h" 35 #include "hsi_struct_def.h" 36 37 static int bnxt_hwrm_err_map(uint16_t err); 38 static inline int _is_valid_ether_addr(uint8_t *); 39 static inline void get_random_ether_addr(uint8_t *); 40 static void bnxt_hwrm_set_link_common(struct bnxt_softc *softc, 41 struct hwrm_port_phy_cfg_input *req); 42 static void bnxt_hwrm_set_pause_common(struct bnxt_softc *softc, 43 struct hwrm_port_phy_cfg_input *req); 44 static void bnxt_hwrm_set_eee(struct bnxt_softc *softc, 45 struct hwrm_port_phy_cfg_input *req); 46 47 /* NVRam stuff has a five minute timeout */ 48 #define BNXT_NVM_TIMEO (5 * 60 * 1000) 49 50 #define BNXT_RX_STATS_PRI_ENTRY(counter, n) \ 51 BNXT_RX_STATS_EXT_OFFSET(counter##_cos0) 52 53 #define BNXT_TX_STATS_PRI_ENTRY(counter, n) \ 54 BNXT_TX_STATS_EXT_OFFSET(counter##_cos0) 55 56 #define BNXT_RX_STATS_PRI_ENTRIES(counter) \ 57 BNXT_RX_STATS_PRI_ENTRY(counter, 0), \ 58 BNXT_RX_STATS_PRI_ENTRY(counter, 1), \ 59 BNXT_RX_STATS_PRI_ENTRY(counter, 2), \ 60 BNXT_RX_STATS_PRI_ENTRY(counter, 3), \ 61 BNXT_RX_STATS_PRI_ENTRY(counter, 4), \ 62 BNXT_RX_STATS_PRI_ENTRY(counter, 5), \ 63 BNXT_RX_STATS_PRI_ENTRY(counter, 6), \ 64 BNXT_RX_STATS_PRI_ENTRY(counter, 7) 65 66 #define BNXT_TX_STATS_PRI_ENTRIES(counter) \ 67 BNXT_TX_STATS_PRI_ENTRY(counter, 0), \ 68 BNXT_TX_STATS_PRI_ENTRY(counter, 1), \ 69 BNXT_TX_STATS_PRI_ENTRY(counter, 2), \ 70 BNXT_TX_STATS_PRI_ENTRY(counter, 3), \ 71 BNXT_TX_STATS_PRI_ENTRY(counter, 4), \ 72 BNXT_TX_STATS_PRI_ENTRY(counter, 5), \ 73 BNXT_TX_STATS_PRI_ENTRY(counter, 6), \ 74 BNXT_TX_STATS_PRI_ENTRY(counter, 7) 75 76 77 long bnxt_rx_bytes_pri_arr_base_off[] = {BNXT_RX_STATS_PRI_ENTRIES(rx_bytes)}; 78 long bnxt_rx_pkts_pri_arr_base_off[] = {BNXT_RX_STATS_PRI_ENTRIES(rx_packets)}; 79 long bnxt_tx_bytes_pri_arr_base_off[] = {BNXT_TX_STATS_PRI_ENTRIES(tx_bytes)}; 80 long bnxt_tx_pkts_pri_arr_base_off[] = {BNXT_TX_STATS_PRI_ENTRIES(tx_packets)}; 81 82 static int 83 bnxt_hwrm_err_map(uint16_t err) 84 { 85 int rc; 86 87 switch (err) { 88 case HWRM_ERR_CODE_SUCCESS: 89 return 0; 90 case HWRM_ERR_CODE_INVALID_PARAMS: 91 case HWRM_ERR_CODE_INVALID_FLAGS: 92 case HWRM_ERR_CODE_INVALID_ENABLES: 93 return EINVAL; 94 case HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED: 95 return EACCES; 96 case HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR: 97 return ENOMEM; 98 case HWRM_ERR_CODE_CMD_NOT_SUPPORTED: 99 return ENOSYS; 100 case HWRM_ERR_CODE_FAIL: 101 return EIO; 102 case HWRM_ERR_CODE_HWRM_ERROR: 103 case HWRM_ERR_CODE_UNKNOWN_ERR: 104 default: 105 return EDOOFUS; 106 } 107 108 return rc; 109 } 110 111 int 112 bnxt_alloc_hwrm_dma_mem(struct bnxt_softc *softc) 113 { 114 int rc; 115 116 rc = iflib_dma_alloc(softc->ctx, PAGE_SIZE, &softc->hwrm_cmd_resp, 117 BUS_DMA_NOWAIT); 118 return rc; 119 } 120 121 void 122 bnxt_free_hwrm_dma_mem(struct bnxt_softc *softc) 123 { 124 if (softc->hwrm_cmd_resp.idi_vaddr) 125 iflib_dma_free(&softc->hwrm_cmd_resp); 126 softc->hwrm_cmd_resp.idi_vaddr = NULL; 127 return; 128 } 129 130 void 131 bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *softc, void *request, 132 uint16_t req_type) 133 { 134 struct input *req = request; 135 136 req->req_type = htole16(req_type); 137 req->cmpl_ring = 0xffff; 138 req->target_id = 0xffff; 139 req->resp_addr = htole64(softc->hwrm_cmd_resp.idi_paddr); 140 } 141 142 int 143 _hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len) 144 { 145 struct input *req = msg; 146 struct hwrm_err_output *resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; 147 uint32_t *data = msg; 148 int i; 149 uint8_t *valid; 150 uint16_t err; 151 uint16_t max_req_len = BNXT_HWRM_MAX_REQ_LEN; 152 struct hwrm_short_input short_input = {0}; 153 154 /* TODO: DMASYNC in here. */ 155 req->seq_id = htole16(softc->hwrm_cmd_seq++); 156 memset(resp, 0, PAGE_SIZE); 157 158 if (BNXT_NO_FW_ACCESS(softc) && 159 (req->req_type != HWRM_FUNC_RESET && req->req_type != HWRM_VER_GET)) 160 return -EINVAL; 161 162 if ((softc->flags & BNXT_FLAG_SHORT_CMD) || 163 msg_len > BNXT_HWRM_MAX_REQ_LEN) { 164 void *short_cmd_req = softc->hwrm_short_cmd_req_addr.idi_vaddr; 165 uint16_t max_msg_len; 166 167 /* Set boundary for maximum extended request length for short 168 * cmd format. If passed up from device use the max supported 169 * internal req length. 170 */ 171 172 max_msg_len = softc->hwrm_max_ext_req_len; 173 174 175 memcpy(short_cmd_req, req, msg_len); 176 if (msg_len < max_msg_len) 177 memset((uint8_t *) short_cmd_req + msg_len, 0, 178 max_msg_len - msg_len); 179 180 short_input.req_type = req->req_type; 181 short_input.signature = 182 htole16(HWRM_SHORT_INPUT_SIGNATURE_SHORT_CMD); 183 short_input.size = htole16(msg_len); 184 short_input.req_addr = 185 htole64(softc->hwrm_short_cmd_req_addr.idi_paddr); 186 187 data = (uint32_t *)&short_input; 188 msg_len = sizeof(short_input); 189 190 /* Sync memory write before updating doorbell */ 191 wmb(); 192 193 max_req_len = BNXT_HWRM_SHORT_REQ_LEN; 194 } 195 196 /* Write request msg to hwrm channel */ 197 for (i = 0; i < msg_len; i += 4) { 198 bus_space_write_4(softc->hwrm_bar.tag, 199 softc->hwrm_bar.handle, 200 i, *data); 201 data++; 202 } 203 204 /* Clear to the end of the request buffer */ 205 for (i = msg_len; i < max_req_len; i += 4) 206 bus_space_write_4(softc->hwrm_bar.tag, softc->hwrm_bar.handle, 207 i, 0); 208 209 /* Ring channel doorbell */ 210 bus_space_write_4(softc->hwrm_bar.tag, 211 softc->hwrm_bar.handle, 212 0x100, htole32(1)); 213 214 /* Check if response len is updated */ 215 for (i = 0; i < softc->hwrm_cmd_timeo; i++) { 216 if (resp->resp_len && resp->resp_len <= 4096) 217 break; 218 DELAY(1000); 219 } 220 if (i >= softc->hwrm_cmd_timeo) { 221 device_printf(softc->dev, 222 "Timeout sending %s: (timeout: %u) seq: %d\n", 223 GET_HWRM_REQ_TYPE(req->req_type), softc->hwrm_cmd_timeo, 224 le16toh(req->seq_id)); 225 return ETIMEDOUT; 226 } 227 /* Last byte of resp contains the valid key */ 228 valid = (uint8_t *)resp + resp->resp_len - 1; 229 for (i = 0; i < softc->hwrm_cmd_timeo; i++) { 230 if (*valid == HWRM_RESP_VALID_KEY) 231 break; 232 DELAY(1000); 233 } 234 if (i >= softc->hwrm_cmd_timeo) { 235 device_printf(softc->dev, "Timeout sending %s: " 236 "(timeout: %u) msg {0x%x 0x%x} len:%d v: %d\n", 237 GET_HWRM_REQ_TYPE(req->req_type), 238 softc->hwrm_cmd_timeo, le16toh(req->req_type), 239 le16toh(req->seq_id), msg_len, 240 *valid); 241 return ETIMEDOUT; 242 } 243 244 err = le16toh(resp->error_code); 245 if (err) { 246 /* HWRM_ERR_CODE_FAIL is a "normal" error, don't log */ 247 if (err != HWRM_ERR_CODE_FAIL) { 248 device_printf(softc->dev, 249 "%s command returned %s error.\n", 250 GET_HWRM_REQ_TYPE(req->req_type), 251 GET_HWRM_ERROR_CODE(err)); 252 } 253 return bnxt_hwrm_err_map(err); 254 } 255 256 return 0; 257 } 258 259 int 260 hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len) 261 { 262 int rc; 263 264 BNXT_HWRM_LOCK(softc); 265 rc = _hwrm_send_message(softc, msg, msg_len); 266 BNXT_HWRM_UNLOCK(softc); 267 return rc; 268 } 269 270 int 271 bnxt_hwrm_queue_qportcfg(struct bnxt_softc *softc, uint32_t path_dir) 272 { 273 int rc = 0; 274 struct hwrm_queue_qportcfg_input req = {0}; 275 struct hwrm_queue_qportcfg_output *resp = 276 (void *)softc->hwrm_cmd_resp.idi_vaddr; 277 uint8_t max_tc, max_lltc, *max_q; 278 uint8_t queue_profile, queue_id; 279 struct bnxt_queue_info *q_info; 280 uint8_t i, j, *qptr, *q_ids; 281 bool no_rdma; 282 283 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_QPORTCFG); 284 285 BNXT_HWRM_LOCK(softc); 286 rc = _hwrm_send_message(softc, &req, sizeof(req)); 287 if (rc) 288 goto qportcfg_exit; 289 290 if (!resp->max_configurable_queues) { 291 rc = -EINVAL; 292 goto qportcfg_exit; 293 } 294 295 if (resp->queue_cfg_info & HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG) { 296 softc->is_asym_q = true; 297 /* bnxt_init_cosq_names(softc, path_dir); */ 298 } else { 299 softc->is_asym_q = false; 300 /* bnxt_free_stats_cosqnames_mem(softc); */ 301 } 302 303 max_tc = min_t(uint8_t, resp->max_configurable_queues, BNXT_MAX_QUEUE); 304 max_lltc = resp->max_configurable_lossless_queues; 305 306 /* 307 * No RDMA support yet. 308 * no_rdma = !(softc->flags & BNXT_FLAG_ROCE_CAP); 309 */ 310 no_rdma = true; 311 qptr = &resp->queue_id0; 312 313 if (path_dir == HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX) { 314 q_info = softc->tx_q_info; 315 q_ids = softc->tx_q_ids; 316 max_q = &softc->tx_max_q; 317 } else { 318 q_info = softc->rx_q_info; 319 q_ids = softc->rx_q_ids; 320 max_q = &softc->rx_max_q; 321 } 322 323 for (i = 0, j = 0; i < max_tc; i++) { 324 queue_id = *qptr; 325 qptr++; 326 327 queue_profile = *qptr; 328 qptr++; 329 330 q_info[j].queue_id = queue_id; 331 q_info[j].queue_profile = queue_profile; 332 q_ids[i] = queue_id; 333 334 softc->tc_to_qidx[j] = j; 335 336 if (!BNXT_CNPQ(q_info[j].queue_profile) || 337 (no_rdma && BNXT_PF(softc))) 338 j++; 339 } 340 *max_q = max_tc; 341 max_tc = max_t(uint8_t, j, 1); 342 softc->max_tc = softc->max_tc ? min(softc->max_tc, max_tc) : max_tc; 343 softc->max_lltc = softc->max_lltc ? min(softc->max_lltc, max_lltc) : max_lltc; 344 345 if (softc->max_lltc > softc->max_tc) 346 softc->max_lltc = softc->max_tc; 347 348 qportcfg_exit: 349 BNXT_HWRM_UNLOCK(softc); 350 return rc; 351 } 352 353 static int bnxt_alloc_all_ctx_pg_info(struct bnxt_softc *softc) 354 { 355 struct bnxt_ctx_mem_info *ctx = softc->ctx_mem; 356 u16 type; 357 358 for (type = 0; type < BNXT_CTX_MAX; type++) { 359 struct bnxt_ctx_mem_type *ctxm = &ctx->ctx_arr[type]; 360 int n = 1; 361 362 if (!ctxm->max_entries || ctxm->pg_info) 363 continue; 364 365 if (ctxm->instance_bmap) 366 n = hweight32(ctxm->instance_bmap); 367 ctxm->pg_info = kcalloc(n, sizeof(*ctxm->pg_info), GFP_KERNEL); 368 if (!ctxm->pg_info) 369 return -ENOMEM; 370 } 371 return 0; 372 } 373 374 static void bnxt_init_ctx_initializer(struct bnxt_ctx_mem_type *ctxm, 375 u8 init_val, u8 init_offset, 376 bool init_mask_set) 377 { 378 ctxm->init_value = init_val; 379 ctxm->init_offset = BNXT_CTX_INIT_INVALID_OFFSET; 380 if (init_mask_set) 381 ctxm->init_offset = init_offset * 4; 382 else 383 ctxm->init_value = 0; 384 } 385 386 int bnxt_hwrm_func_backing_store_qcaps(struct bnxt_softc *softc) 387 { 388 struct hwrm_func_backing_store_qcaps_input req = {0}; 389 struct hwrm_func_backing_store_qcaps_output *resp = 390 (void *)softc->hwrm_cmd_resp.idi_vaddr; 391 int rc; 392 393 if (softc->hwrm_spec_code < 0x10902 || softc->ctx_mem) 394 return 0; 395 396 if (BNXT_VF(softc)) 397 return 0; 398 399 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_BACKING_STORE_QCAPS); 400 BNXT_HWRM_LOCK(softc); 401 rc = _hwrm_send_message(softc, &req, sizeof(req)); 402 if (!rc) { 403 struct bnxt_ctx_mem_type *ctxm; 404 struct bnxt_ctx_mem_info *ctx; 405 u8 init_val, init_idx = 0; 406 u16 init_mask; 407 408 ctx = softc->ctx_mem; 409 if (!ctx) { 410 ctx = malloc(sizeof(*ctx), M_DEVBUF, M_NOWAIT | M_ZERO); 411 if (!ctx) { 412 rc = -ENOMEM; 413 goto ctx_err; 414 } 415 softc->ctx_mem = ctx; 416 } 417 init_val = resp->ctx_kind_initializer; 418 init_mask = le16_to_cpu(resp->ctx_init_mask); 419 420 ctxm = &ctx->ctx_arr[BNXT_CTX_QP]; 421 ctxm->max_entries = le32_to_cpu(resp->qp_max_entries); 422 ctxm->qp_qp1_entries = le16_to_cpu(resp->qp_min_qp1_entries); 423 ctxm->qp_l2_entries = le16_to_cpu(resp->qp_max_l2_entries); 424 ctxm->entry_size = le16_to_cpu(resp->qp_entry_size); 425 bnxt_init_ctx_initializer(ctxm, init_val, resp->qp_init_offset, 426 (init_mask & (1 << init_idx++)) != 0); 427 428 ctxm = &ctx->ctx_arr[BNXT_CTX_SRQ]; 429 ctxm->srq_l2_entries = le16_to_cpu(resp->srq_max_l2_entries); 430 ctxm->max_entries = le32_to_cpu(resp->srq_max_entries); 431 ctxm->entry_size = le16_to_cpu(resp->srq_entry_size); 432 bnxt_init_ctx_initializer(ctxm, init_val, resp->srq_init_offset, 433 (init_mask & (1 << init_idx++)) != 0); 434 435 ctxm = &ctx->ctx_arr[BNXT_CTX_CQ]; 436 ctxm->cq_l2_entries = le16_to_cpu(resp->cq_max_l2_entries); 437 ctxm->max_entries = le32_to_cpu(resp->cq_max_entries); 438 ctxm->entry_size = le16_to_cpu(resp->cq_entry_size); 439 bnxt_init_ctx_initializer(ctxm, init_val, resp->cq_init_offset, 440 (init_mask & (1 << init_idx++)) != 0); 441 442 ctxm = &ctx->ctx_arr[BNXT_CTX_VNIC]; 443 ctxm->vnic_entries = le32_to_cpu(resp->vnic_max_vnic_entries); 444 ctxm->max_entries = ctxm->vnic_entries + 445 le16_to_cpu(resp->vnic_max_ring_table_entries); 446 ctxm->entry_size = le16_to_cpu(resp->vnic_entry_size); 447 bnxt_init_ctx_initializer(ctxm, init_val, 448 resp->vnic_init_offset, 449 (init_mask & (1 << init_idx++)) != 0); 450 451 ctxm = &ctx->ctx_arr[BNXT_CTX_STAT]; 452 ctxm->max_entries = le32_to_cpu(resp->stat_max_entries); 453 ctxm->entry_size = le16_to_cpu(resp->stat_entry_size); 454 bnxt_init_ctx_initializer(ctxm, init_val, 455 resp->stat_init_offset, 456 (init_mask & (1 << init_idx++)) != 0); 457 458 ctxm = &ctx->ctx_arr[BNXT_CTX_STQM]; 459 ctxm->entry_size = le16_to_cpu(resp->tqm_entry_size); 460 ctxm->min_entries = le32_to_cpu(resp->tqm_min_entries_per_ring); 461 ctxm->max_entries = le32_to_cpu(resp->tqm_max_entries_per_ring); 462 ctxm->entry_multiple = resp->tqm_entries_multiple; 463 if (!ctxm->entry_multiple) 464 ctxm->entry_multiple = 1; 465 466 memcpy(&ctx->ctx_arr[BNXT_CTX_FTQM], ctxm, sizeof(*ctxm)); 467 468 ctxm = &ctx->ctx_arr[BNXT_CTX_MRAV]; 469 ctxm->max_entries = le32_to_cpu(resp->mrav_max_entries); 470 ctxm->entry_size = le16_to_cpu(resp->mrav_entry_size); 471 ctxm->mrav_num_entries_units = 472 le16_to_cpu(resp->mrav_num_entries_units); 473 bnxt_init_ctx_initializer(ctxm, init_val, 474 resp->mrav_init_offset, 475 (init_mask & (1 << init_idx++)) != 0); 476 477 ctxm = &ctx->ctx_arr[BNXT_CTX_TIM]; 478 ctxm->entry_size = le16_to_cpu(resp->tim_entry_size); 479 ctxm->max_entries = le32_to_cpu(resp->tim_max_entries); 480 481 ctx->tqm_fp_rings_count = resp->tqm_fp_rings_count; 482 if (!ctx->tqm_fp_rings_count) 483 ctx->tqm_fp_rings_count = softc->tx_max_q; 484 else if (ctx->tqm_fp_rings_count > BNXT_MAX_TQM_FP_LEGACY_RINGS) 485 ctx->tqm_fp_rings_count = BNXT_MAX_TQM_FP_LEGACY_RINGS; 486 if (ctx->tqm_fp_rings_count == BNXT_MAX_TQM_FP_LEGACY_RINGS && 487 softc->hwrm_max_ext_req_len >= BNXT_BACKING_STORE_CFG_LEN) { 488 ctx->tqm_fp_rings_count += resp->tqm_fp_rings_count_ext; 489 if (ctx->tqm_fp_rings_count > BNXT_MAX_TQM_FP_RINGS) 490 ctx->tqm_fp_rings_count = BNXT_MAX_TQM_FP_RINGS; 491 } 492 ctxm = &ctx->ctx_arr[BNXT_CTX_FTQM]; 493 memcpy(ctxm, &ctx->ctx_arr[BNXT_CTX_STQM], sizeof(*ctxm)); 494 ctxm->instance_bmap = (1 << ctx->tqm_fp_rings_count) - 1; 495 496 rc = bnxt_alloc_all_ctx_pg_info(softc); 497 } else { 498 rc = 0; 499 } 500 ctx_err: 501 BNXT_HWRM_UNLOCK(softc); 502 return rc; 503 } 504 505 #define HWRM_FUNC_BACKING_STORE_CFG_INPUT_DFLT_ENABLES \ 506 (HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_QP | \ 507 HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_SRQ | \ 508 HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_CQ | \ 509 HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_VNIC | \ 510 HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_STAT) 511 512 static void bnxt_hwrm_set_pg_attr(struct bnxt_ring_mem_info *rmem, uint8_t *pg_attr, 513 uint64_t *pg_dir) 514 { 515 uint8_t pg_size = 0; 516 517 if (BNXT_PAGE_SHIFT == 13) 518 pg_size = 1 << 4; 519 else if (BNXT_PAGE_SIZE == 16) 520 pg_size = 2 << 4; 521 522 *pg_attr = pg_size; 523 if (rmem->depth >= 1) { 524 if (rmem->depth == 2) 525 *pg_attr |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_LVL_2; 526 else 527 *pg_attr |= HWRM_FUNC_BACKING_STORE_CFG_INPUT_QPC_LVL_LVL_1; 528 *pg_dir = htole64(rmem->pg_tbl.idi_paddr); 529 } else { 530 *pg_dir = htole64(rmem->pg_arr[0].idi_paddr); 531 } 532 } 533 534 int bnxt_hwrm_func_backing_store_cfg(struct bnxt_softc *softc, uint32_t enables) 535 { 536 struct hwrm_func_backing_store_cfg_input req = {0}; 537 struct bnxt_ctx_mem_info *ctx = softc->ctx_mem; 538 struct bnxt_ctx_pg_info *ctx_pg; 539 struct bnxt_ctx_mem_type *ctxm; 540 u32 req_len = sizeof(req); 541 __le32 *num_entries; 542 u32 ena, flags = 0; 543 __le64 *pg_dir; 544 u8 *pg_attr; 545 int i; 546 547 if (!ctx) 548 return 0; 549 550 if (req_len > softc->hwrm_max_ext_req_len) 551 req_len = BNXT_BACKING_STORE_CFG_LEGACY_LEN; 552 553 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_BACKING_STORE_CFG); 554 req.enables = htole32(enables); 555 556 if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_QP) { 557 ctxm = &ctx->ctx_arr[BNXT_CTX_QP]; 558 ctx_pg = ctxm->pg_info; 559 req.qp_num_entries = cpu_to_le32(ctx_pg->entries); 560 req.qp_num_qp1_entries = cpu_to_le16(ctxm->qp_qp1_entries); 561 req.qp_num_l2_entries = cpu_to_le16(ctxm->qp_l2_entries); 562 req.qp_entry_size = cpu_to_le16(ctxm->entry_size); 563 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, 564 &req.qpc_pg_size_qpc_lvl, 565 &req.qpc_page_dir); 566 } 567 if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_SRQ) { 568 ctxm = &ctx->ctx_arr[BNXT_CTX_SRQ]; 569 ctx_pg = ctxm->pg_info; 570 req.srq_num_entries = cpu_to_le32(ctx_pg->entries); 571 req.srq_num_l2_entries = cpu_to_le16(ctxm->srq_l2_entries); 572 req.srq_entry_size = cpu_to_le16(ctxm->entry_size); 573 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, 574 &req.srq_pg_size_srq_lvl, 575 &req.srq_page_dir); 576 } 577 if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_CQ) { 578 ctxm = &ctx->ctx_arr[BNXT_CTX_CQ]; 579 ctx_pg = ctxm->pg_info; 580 req.cq_num_entries = cpu_to_le32(ctx_pg->entries); 581 req.cq_num_l2_entries = cpu_to_le16(ctxm->cq_l2_entries); 582 req.cq_entry_size = cpu_to_le16(ctxm->entry_size); 583 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, 584 &req.cq_pg_size_cq_lvl, 585 &req.cq_page_dir); 586 } 587 if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_MRAV) { 588 ctxm = &ctx->ctx_arr[BNXT_CTX_MRAV]; 589 ctx_pg = ctxm->pg_info; 590 req.mrav_num_entries = cpu_to_le32(ctx_pg->entries); 591 if (ctxm->mrav_num_entries_units) 592 flags |= 593 HWRM_FUNC_BACKING_STORE_CFG_INPUT_FLAGS_MRAV_RESERVATION_SPLIT; 594 req.mrav_entry_size = cpu_to_le16(ctxm->entry_size); 595 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, 596 &req.mrav_pg_size_mrav_lvl, 597 &req.mrav_page_dir); 598 } 599 if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TIM) { 600 ctxm = &ctx->ctx_arr[BNXT_CTX_TIM]; 601 ctx_pg = ctxm->pg_info; 602 req.tim_num_entries = cpu_to_le32(ctx_pg->entries); 603 req.tim_entry_size = cpu_to_le16(ctxm->entry_size); 604 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, 605 &req.tim_pg_size_tim_lvl, 606 &req.tim_page_dir); 607 } 608 if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_VNIC) { 609 ctxm = &ctx->ctx_arr[BNXT_CTX_VNIC]; 610 ctx_pg = ctxm->pg_info; 611 req.vnic_num_vnic_entries = cpu_to_le16(ctxm->vnic_entries); 612 req.vnic_num_ring_table_entries = 613 cpu_to_le16(ctxm->max_entries - ctxm->vnic_entries); 614 req.vnic_entry_size = cpu_to_le16(ctxm->entry_size); 615 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, 616 &req.vnic_pg_size_vnic_lvl, 617 &req.vnic_page_dir); 618 } 619 if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_STAT) { 620 ctxm = &ctx->ctx_arr[BNXT_CTX_STAT]; 621 ctx_pg = ctxm->pg_info; 622 req.stat_num_entries = cpu_to_le32(ctxm->max_entries); 623 req.stat_entry_size = cpu_to_le16(ctxm->entry_size); 624 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, 625 &req.stat_pg_size_stat_lvl, 626 &req.stat_page_dir); 627 } 628 ctxm = &ctx->ctx_arr[BNXT_CTX_STQM]; 629 for (i = 0, num_entries = &req.tqm_sp_num_entries, 630 pg_attr = &req.tqm_sp_pg_size_tqm_sp_lvl, 631 pg_dir = &req.tqm_sp_page_dir, 632 ena = HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_SP, 633 ctx_pg = ctxm->pg_info; 634 i < BNXT_MAX_TQM_LEGACY_RINGS; 635 ctx_pg = &ctx->ctx_arr[BNXT_CTX_FTQM].pg_info[i], 636 i++, num_entries++, pg_attr++, pg_dir++, ena <<= 1) { 637 if (!(enables & ena)) 638 continue; 639 640 req.tqm_entry_size = cpu_to_le16(ctxm->entry_size); 641 *num_entries = cpu_to_le32(ctx_pg->entries); 642 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, pg_attr, pg_dir); 643 } 644 if (enables & HWRM_FUNC_BACKING_STORE_CFG_INPUT_ENABLES_TQM_RING8) { 645 pg_attr = &req.tqm_ring8_pg_size_tqm_ring_lvl; 646 pg_dir = &req.tqm_ring8_page_dir; 647 ctx_pg = &ctx->ctx_arr[BNXT_CTX_FTQM].pg_info[8]; 648 req.tqm_ring8_num_entries = cpu_to_le32(ctx_pg->entries); 649 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, pg_attr, pg_dir); 650 } 651 req.flags = cpu_to_le32(flags); 652 return hwrm_send_message(softc, &req, sizeof(req)); 653 } 654 655 int bnxt_hwrm_func_resc_qcaps(struct bnxt_softc *softc, bool all) 656 { 657 struct hwrm_func_resource_qcaps_output *resp = 658 (void *)softc->hwrm_cmd_resp.idi_vaddr; 659 struct hwrm_func_resource_qcaps_input req = {0}; 660 struct bnxt_hw_resc *hw_resc = &softc->hw_resc; 661 int rc; 662 663 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_RESOURCE_QCAPS); 664 req.fid = htole16(0xffff); 665 666 BNXT_HWRM_LOCK(softc); 667 rc = _hwrm_send_message(softc, &req, sizeof(req)); 668 if (rc) { 669 rc = -EIO; 670 goto hwrm_func_resc_qcaps_exit; 671 } 672 673 hw_resc->max_tx_sch_inputs = le16toh(resp->max_tx_scheduler_inputs); 674 if (!all) 675 goto hwrm_func_resc_qcaps_exit; 676 677 hw_resc->min_rsscos_ctxs = le16toh(resp->min_rsscos_ctx); 678 hw_resc->max_rsscos_ctxs = le16toh(resp->max_rsscos_ctx); 679 hw_resc->min_cp_rings = le16toh(resp->min_cmpl_rings); 680 hw_resc->max_cp_rings = le16toh(resp->max_cmpl_rings); 681 hw_resc->min_tx_rings = le16toh(resp->min_tx_rings); 682 hw_resc->max_tx_rings = le16toh(resp->max_tx_rings); 683 hw_resc->min_rx_rings = le16toh(resp->min_rx_rings); 684 hw_resc->max_rx_rings = le16toh(resp->max_rx_rings); 685 hw_resc->min_hw_ring_grps = le16toh(resp->min_hw_ring_grps); 686 hw_resc->max_hw_ring_grps = le16toh(resp->max_hw_ring_grps); 687 hw_resc->min_l2_ctxs = le16toh(resp->min_l2_ctxs); 688 hw_resc->max_l2_ctxs = le16toh(resp->max_l2_ctxs); 689 hw_resc->min_vnics = le16toh(resp->min_vnics); 690 hw_resc->max_vnics = le16toh(resp->max_vnics); 691 hw_resc->min_stat_ctxs = le16toh(resp->min_stat_ctx); 692 hw_resc->max_stat_ctxs = le16toh(resp->max_stat_ctx); 693 694 if (BNXT_CHIP_P5(softc)) { 695 hw_resc->max_nqs = le16toh(resp->max_msix); 696 hw_resc->max_hw_ring_grps = hw_resc->max_rx_rings; 697 } 698 699 hwrm_func_resc_qcaps_exit: 700 BNXT_HWRM_UNLOCK(softc); 701 return rc; 702 } 703 704 int bnxt_hwrm_func_backing_store_cfg_v2(struct bnxt_softc *softc, 705 struct bnxt_ctx_mem_type *ctxm, 706 bool last) 707 { 708 struct hwrm_func_backing_store_cfg_v2_input req = {0}; 709 u32 instance_bmap = ctxm->instance_bmap; 710 int i, j, rc = 0, n = 1; 711 __le32 *p; 712 713 if (!(ctxm->flags & BNXT_CTX_MEM_TYPE_VALID) || !ctxm->pg_info) 714 return 0; 715 716 if (instance_bmap) 717 n = hweight32(ctxm->instance_bmap); 718 else 719 instance_bmap = 1; 720 721 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_BACKING_STORE_CFG_V2); 722 723 req.type = cpu_to_le16(ctxm->type); 724 req.entry_size = cpu_to_le16(ctxm->entry_size); 725 for (i = 0, p = &req.split_entry_0; i < ctxm->split_entry_cnt; i++) 726 p[i] = cpu_to_le32(ctxm->split[i]); 727 for (i = 0, j = 0; j < n && !rc; i++) { 728 struct bnxt_ctx_pg_info *ctx_pg; 729 730 if (!(instance_bmap & (1 << i))) 731 continue; 732 req.instance = cpu_to_le16(i); 733 ctx_pg = &ctxm->pg_info[j++]; 734 if (!ctx_pg->entries) 735 continue; 736 req.num_entries = cpu_to_le32(ctx_pg->entries); 737 bnxt_hwrm_set_pg_attr(&ctx_pg->ring_mem, 738 &req.page_size_pbl_level, 739 &req.page_dir); 740 if (last && j == (n - 1)) 741 req.flags = 742 cpu_to_le32(HWRM_FUNC_BACKING_STORE_CFG_V2_INPUT_FLAGS_BS_CFG_ALL_DONE); 743 rc = hwrm_send_message(softc, &req, sizeof(req)); 744 } 745 return rc; 746 } 747 748 int 749 bnxt_hwrm_passthrough(struct bnxt_softc *softc, void *req, uint32_t req_len, 750 void *resp, uint32_t resp_len, uint32_t app_timeout) 751 { 752 int rc = 0; 753 void *output = (void *)softc->hwrm_cmd_resp.idi_vaddr; 754 struct input *input = req; 755 uint32_t old_timeo; 756 757 input->resp_addr = htole64(softc->hwrm_cmd_resp.idi_paddr); 758 BNXT_HWRM_LOCK(softc); 759 old_timeo = softc->hwrm_cmd_timeo; 760 if (input->req_type == HWRM_NVM_INSTALL_UPDATE) 761 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 762 else 763 softc->hwrm_cmd_timeo = max(app_timeout, softc->hwrm_cmd_timeo); 764 rc = _hwrm_send_message(softc, req, req_len); 765 softc->hwrm_cmd_timeo = old_timeo; 766 if (rc) { 767 device_printf(softc->dev, "%s: %s command failed with rc: 0x%x\n", 768 __FUNCTION__, GET_HWRM_REQ_TYPE(input->req_type), rc); 769 goto fail; 770 } 771 772 memcpy(resp, output, resp_len); 773 fail: 774 BNXT_HWRM_UNLOCK(softc); 775 return rc; 776 } 777 778 779 int 780 bnxt_hwrm_ver_get(struct bnxt_softc *softc) 781 { 782 struct hwrm_ver_get_input req = {0}; 783 struct hwrm_ver_get_output *resp = 784 (void *)softc->hwrm_cmd_resp.idi_vaddr; 785 int rc; 786 const char nastr[] = "<not installed>"; 787 const char naver[] = "<N/A>"; 788 uint32_t dev_caps_cfg; 789 uint16_t fw_maj, fw_min, fw_bld, fw_rsv, len; 790 791 softc->hwrm_max_req_len = HWRM_MAX_REQ_LEN; 792 softc->hwrm_cmd_timeo = 1000; 793 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VER_GET); 794 795 req.hwrm_intf_maj = HWRM_VERSION_MAJOR; 796 req.hwrm_intf_min = HWRM_VERSION_MINOR; 797 req.hwrm_intf_upd = HWRM_VERSION_UPDATE; 798 799 BNXT_HWRM_LOCK(softc); 800 rc = _hwrm_send_message(softc, &req, sizeof(req)); 801 if (rc) 802 goto fail; 803 804 snprintf(softc->ver_info->hwrm_if_ver, BNXT_VERSTR_SIZE, "%d.%d.%d", 805 resp->hwrm_intf_maj_8b, resp->hwrm_intf_min_8b, resp->hwrm_intf_upd_8b); 806 softc->ver_info->hwrm_if_major = resp->hwrm_intf_maj_8b; 807 softc->ver_info->hwrm_if_minor = resp->hwrm_intf_min_8b; 808 softc->ver_info->hwrm_if_update = resp->hwrm_intf_upd_8b; 809 strlcpy(softc->ver_info->driver_hwrm_if_ver, HWRM_VERSION_STR, 810 BNXT_VERSTR_SIZE); 811 strlcpy(softc->ver_info->hwrm_fw_name, resp->hwrm_fw_name, 812 BNXT_NAME_SIZE); 813 814 softc->hwrm_spec_code = resp->hwrm_intf_maj_8b << 16 | 815 resp->hwrm_intf_min_8b << 8 | 816 resp->hwrm_intf_upd_8b; 817 if (resp->hwrm_intf_maj_8b < 1) { 818 device_printf(softc->dev, "HWRM interface %d.%d.%d is older " 819 "than 1.0.0.\n", resp->hwrm_intf_maj_8b, 820 resp->hwrm_intf_min_8b, resp->hwrm_intf_upd_8b); 821 device_printf(softc->dev, "Please update firmware with HWRM " 822 "interface 1.0.0 or newer.\n"); 823 } 824 if (resp->mgmt_fw_major == 0 && resp->mgmt_fw_minor == 0 && 825 resp->mgmt_fw_build == 0) { 826 strlcpy(softc->ver_info->mgmt_fw_ver, naver, BNXT_VERSTR_SIZE); 827 strlcpy(softc->ver_info->mgmt_fw_name, nastr, BNXT_NAME_SIZE); 828 } 829 else { 830 snprintf(softc->ver_info->mgmt_fw_ver, FW_VER_STR_LEN, 831 "%d.%d.%d.%d", resp->mgmt_fw_major, resp->mgmt_fw_minor, 832 resp->mgmt_fw_build, resp->mgmt_fw_patch); 833 strlcpy(softc->ver_info->mgmt_fw_name, resp->mgmt_fw_name, 834 BNXT_NAME_SIZE); 835 } 836 if (resp->netctrl_fw_major == 0 && resp->netctrl_fw_minor == 0 && 837 resp->netctrl_fw_build == 0) { 838 strlcpy(softc->ver_info->netctrl_fw_ver, naver, 839 BNXT_VERSTR_SIZE); 840 strlcpy(softc->ver_info->netctrl_fw_name, nastr, 841 BNXT_NAME_SIZE); 842 } 843 else { 844 snprintf(softc->ver_info->netctrl_fw_ver, FW_VER_STR_LEN, 845 "%d.%d.%d.%d", resp->netctrl_fw_major, resp->netctrl_fw_minor, 846 resp->netctrl_fw_build, resp->netctrl_fw_patch); 847 strlcpy(softc->ver_info->netctrl_fw_name, resp->netctrl_fw_name, 848 BNXT_NAME_SIZE); 849 } 850 if (resp->roce_fw_major == 0 && resp->roce_fw_minor == 0 && 851 resp->roce_fw_build == 0) { 852 strlcpy(softc->ver_info->roce_fw_ver, naver, BNXT_VERSTR_SIZE); 853 strlcpy(softc->ver_info->roce_fw_name, nastr, BNXT_NAME_SIZE); 854 } 855 else { 856 snprintf(softc->ver_info->roce_fw_ver, BNXT_VERSTR_SIZE, 857 "%d.%d.%d.%d", resp->roce_fw_major, resp->roce_fw_minor, 858 resp->roce_fw_build, resp->roce_fw_patch); 859 strlcpy(softc->ver_info->roce_fw_name, resp->roce_fw_name, 860 BNXT_NAME_SIZE); 861 } 862 863 fw_maj = le32toh(resp->hwrm_fw_major); 864 if (softc->hwrm_spec_code > 0x10803 && fw_maj) { 865 fw_min = le16toh(resp->hwrm_fw_minor); 866 fw_bld = le16toh(resp->hwrm_fw_build); 867 fw_rsv = le16toh(resp->hwrm_fw_patch); 868 len = FW_VER_STR_LEN; 869 } else { 870 fw_maj = resp->hwrm_fw_maj_8b; 871 fw_min = resp->hwrm_fw_min_8b; 872 fw_bld = resp->hwrm_fw_bld_8b; 873 fw_rsv = resp->hwrm_fw_rsvd_8b; 874 len = BC_HWRM_STR_LEN; 875 } 876 877 softc->ver_info->fw_ver_code = BNXT_FW_VER_CODE(fw_maj, fw_min, fw_bld, fw_rsv); 878 snprintf (softc->ver_info->fw_ver_str, len, "%d.%d.%d.%d", 879 fw_maj, fw_min, fw_bld, fw_rsv); 880 881 if (strlen(resp->active_pkg_name)) { 882 int fw_ver_len = strlen (softc->ver_info->fw_ver_str); 883 884 snprintf(softc->ver_info->fw_ver_str + fw_ver_len, 885 FW_VER_STR_LEN - fw_ver_len - 1, "/pkg %s", 886 resp->active_pkg_name); 887 softc->fw_cap |= BNXT_FW_CAP_PKG_VER; 888 } 889 890 softc->ver_info->chip_num = le16toh(resp->chip_num); 891 softc->ver_info->chip_rev = resp->chip_rev; 892 softc->ver_info->chip_metal = resp->chip_metal; 893 softc->ver_info->chip_bond_id = resp->chip_bond_id; 894 softc->ver_info->chip_type = resp->chip_platform_type; 895 896 if (resp->hwrm_intf_maj_8b >= 1) { 897 softc->hwrm_max_req_len = le16toh(resp->max_req_win_len); 898 softc->hwrm_max_ext_req_len = le16toh(resp->max_ext_req_len); 899 } 900 softc->hwrm_cmd_timeo = le16toh(resp->def_req_timeout); 901 if (!softc->hwrm_cmd_timeo) 902 softc->hwrm_cmd_timeo = DFLT_HWRM_CMD_TIMEOUT; 903 904 dev_caps_cfg = le32toh(resp->dev_caps_cfg); 905 if ((dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) && 906 (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED)) 907 softc->flags |= BNXT_FLAG_SHORT_CMD; 908 909 if ((dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) && 910 (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED)) 911 softc->fw_cap |= BNXT_FW_CAP_SHORT_CMD; 912 913 if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_KONG_MB_CHNL_SUPPORTED) 914 softc->fw_cap |= BNXT_FW_CAP_KONG_MB_CHNL; 915 916 if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FLOW_HANDLE_64BIT_SUPPORTED) 917 softc->fw_cap |= BNXT_FW_CAP_OVS_64BIT_HANDLE; 918 919 if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_TRUSTED_VF_SUPPORTED) 920 softc->fw_cap |= BNXT_FW_CAP_TRUSTED_VF; 921 922 if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_CFA_ADV_FLOW_MGNT_SUPPORTED) 923 softc->fw_cap |= BNXT_FW_CAP_CFA_ADV_FLOW; 924 925 if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_CFA_EEM_SUPPORTED) 926 softc->fw_cap |= BNXT_FW_CAP_CFA_EEM; 927 928 if (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_CFA_TRUFLOW_SUPPORTED) 929 softc->fw_cap |= BNXT_FW_CAP_TRUFLOW_EN; 930 931 fail: 932 BNXT_HWRM_UNLOCK(softc); 933 return rc; 934 } 935 936 static const u16 bnxt_async_events_arr[] = { 937 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE, 938 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE, 939 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD, 940 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED, 941 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE, 942 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE, 943 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE, 944 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY, 945 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY, 946 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RING_MONITOR_MSG, 947 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DEFAULT_VNIC_CHANGE, 948 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DEBUG_NOTIFICATION, 949 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DEFERRED_RESPONSE, 950 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ECHO_REQUEST, 951 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PPS_TIMESTAMP, 952 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_REPORT, 953 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PHC_UPDATE, 954 }; 955 956 int bnxt_hwrm_func_drv_rgtr(struct bnxt_softc *bp, unsigned long *bmap, int bmap_size, 957 bool async_only) 958 { 959 DECLARE_BITMAP(async_events_bmap, 256); 960 u32 *events = (u32 *)async_events_bmap; 961 struct hwrm_func_drv_rgtr_output *resp = 962 (void *)bp->hwrm_cmd_resp.idi_vaddr; 963 struct hwrm_func_drv_rgtr_input req = {0}; 964 u32 flags = 0; 965 int rc; 966 int i; 967 968 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_DRV_RGTR); 969 req.ver_maj = HWRM_VERSION_MAJOR; 970 req.ver_min = HWRM_VERSION_MINOR; 971 req.ver_upd = HWRM_VERSION_UPDATE; 972 973 req.enables = htole32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_OS_TYPE | 974 HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER | 975 HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD); 976 977 if (bp->fw_cap & BNXT_FW_CAP_HOT_RESET) 978 flags |= HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_HOT_RESET_SUPPORT; 979 if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) 980 flags |= HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_ERROR_RECOVERY_SUPPORT | 981 HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_MASTER_SUPPORT; 982 if (bp->fw_cap & BNXT_FW_CAP_NPAR_1_2) 983 flags |= HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_NPAR_1_2_SUPPORT; 984 flags |= HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_ASYM_QUEUE_CFG_SUPPORT; 985 req.flags = htole32(flags); 986 req.os_type = htole16(HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD); 987 988 if (BNXT_PF(bp)) { 989 req.enables |= 990 htole32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_REQ_FWD); 991 } 992 993 if (bp->fw_cap & BNXT_FW_CAP_OVS_64BIT_HANDLE) 994 req.flags |= cpu_to_le32(HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FLOW_HANDLE_64BIT_MODE); 995 996 memset(async_events_bmap, 0, sizeof(async_events_bmap)); 997 for (i = 0; i < ARRAY_SIZE(bnxt_async_events_arr); i++) { 998 u16 event_id = bnxt_async_events_arr[i]; 999 1000 if (event_id == HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY && 1001 !(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) { 1002 continue; 1003 } 1004 __set_bit(bnxt_async_events_arr[i], async_events_bmap); 1005 } 1006 if (bmap && bmap_size) { 1007 for (i = 0; i < bmap_size; i++) { 1008 if (test_bit(i, bmap)) 1009 __set_bit(i, async_events_bmap); 1010 } 1011 } 1012 for (i = 0; i < 8; i++) 1013 req.async_event_fwd[i] |= htole32(events[i]); 1014 1015 if (async_only) 1016 req.enables = 1017 htole32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD); 1018 1019 rc = hwrm_send_message(bp, &req, sizeof(req)); 1020 1021 if (!rc) { 1022 if (resp->flags & 1023 le32toh(HWRM_FUNC_DRV_RGTR_OUTPUT_FLAGS_IF_CHANGE_SUPPORTED)) 1024 bp->fw_cap |= BNXT_FW_CAP_IF_CHANGE; 1025 } 1026 1027 1028 return rc; 1029 } 1030 1031 int 1032 bnxt_hwrm_func_drv_unrgtr(struct bnxt_softc *softc, bool shutdown) 1033 { 1034 struct hwrm_func_drv_unrgtr_input req = {0}; 1035 1036 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_DRV_UNRGTR); 1037 if (shutdown == true) 1038 req.flags |= 1039 HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN; 1040 return hwrm_send_message(softc, &req, sizeof(req)); 1041 } 1042 1043 static inline int 1044 _is_valid_ether_addr(uint8_t *addr) 1045 { 1046 char zero_addr[6] = { 0, 0, 0, 0, 0, 0 }; 1047 1048 if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) 1049 return (FALSE); 1050 1051 return (TRUE); 1052 } 1053 1054 static inline void 1055 get_random_ether_addr(uint8_t *addr) 1056 { 1057 uint8_t temp[ETHER_ADDR_LEN]; 1058 1059 arc4rand(&temp, sizeof(temp), 0); 1060 temp[0] &= 0xFE; 1061 temp[0] |= 0x02; 1062 bcopy(temp, addr, sizeof(temp)); 1063 } 1064 1065 int 1066 bnxt_hwrm_func_qcaps(struct bnxt_softc *softc) 1067 { 1068 int rc = 0; 1069 struct hwrm_func_qcaps_input req = {0}; 1070 struct hwrm_func_qcaps_output *resp = 1071 (void *)softc->hwrm_cmd_resp.idi_vaddr; 1072 struct bnxt_func_info *func = &softc->func; 1073 uint32_t flags, flags_ext, flags_ext2; 1074 1075 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_QCAPS); 1076 req.fid = htole16(0xffff); 1077 1078 BNXT_HWRM_LOCK(softc); 1079 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1080 if (rc) 1081 goto fail; 1082 1083 flags = htole32(resp->flags); 1084 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED) 1085 softc->flags |= BNXT_FLAG_WOL_CAP; 1086 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_STATS_SUPPORTED) 1087 softc->flags |= BNXT_FLAG_FW_CAP_EXT_STATS; 1088 1089 /* Enable RoCE only on Thor devices */ 1090 if (BNXT_CHIP_P5(softc)) { 1091 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED) 1092 softc->flags |= BNXT_FLAG_ROCEV1_CAP; 1093 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED) 1094 softc->flags |= BNXT_FLAG_ROCEV2_CAP; 1095 } 1096 1097 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_LINK_ADMIN_STATUS_SUPPORTED) 1098 softc->fw_cap |= BNXT_FW_CAP_LINK_ADMIN; 1099 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ADMIN_PF_SUPPORTED) 1100 softc->fw_cap |= BNXT_FW_CAP_ADMIN_PF; 1101 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_HOT_RESET_CAPABLE) 1102 softc->fw_cap |= BNXT_FW_CAP_HOT_RESET; 1103 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERROR_RECOVERY_CAPABLE) 1104 softc->fw_cap |= BNXT_FW_CAP_ERROR_RECOVERY; 1105 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PCIE_STATS_SUPPORTED) 1106 softc->fw_cap |= BNXT_FW_CAP_PCIE_STATS_SUPPORTED; 1107 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_STATS_SUPPORTED) 1108 softc->fw_cap |= BNXT_FW_CAP_EXT_STATS_SUPPORTED; 1109 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERR_RECOVER_RELOAD) 1110 softc->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD; 1111 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_NOTIFY_VF_DEF_VNIC_CHNG_SUPPORTED) 1112 softc->fw_cap |= BNXT_FW_CAP_VF_VNIC_NOTIFY; 1113 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_CRASHDUMP_CMD_SUPPORTED) 1114 softc->fw_cap |= BNXT_FW_CAP_CRASHDUMP; 1115 if (!(flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VLAN_ACCELERATION_TX_DISABLED)) 1116 softc->fw_cap |= BNXT_FW_CAP_VLAN_TX_INSERT; 1117 if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_DBG_QCAPS_CMD_SUPPORTED) 1118 softc->fw_cap |= BNXT_FW_CAP_DBG_QCAPS; 1119 1120 flags_ext = htole32(resp->flags_ext); 1121 if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_EXT_HW_STATS_SUPPORTED) 1122 softc->fw_cap |= BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED; 1123 if (BNXT_PF(softc) && (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_ECN_STATS_SUPPORTED)) 1124 softc->fw_cap |= BNXT_FW_CAP_ECN_STATS; 1125 1126 if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_PTP_PPS_SUPPORTED) 1127 softc->fw_cap |= BNXT_FW_CAP_PTP_PPS; 1128 if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_PTP_PTM_SUPPORTED) 1129 softc->fw_cap |= BNXT_FW_CAP_PTP_PTM; 1130 if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_PTP_64BIT_RTC_SUPPORTED) 1131 softc->fw_cap |= BNXT_FW_CAP_PTP_RTC; 1132 if (BNXT_PF(softc) && (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_HOT_RESET_IF_SUPPORT)) 1133 softc->fw_cap |= BNXT_FW_CAP_HOT_RESET_IF; 1134 if (BNXT_PF(softc) && (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_FW_LIVEPATCH_SUPPORTED)) 1135 softc->fw_cap |= BNXT_FW_CAP_LIVEPATCH; 1136 if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_NPAR_1_2_SUPPORTED) 1137 softc->fw_cap |= BNXT_FW_CAP_NPAR_1_2; 1138 if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_BS_V2_SUPPORTED) 1139 softc->fw_cap |= BNXT_FW_CAP_BACKING_STORE_V2; 1140 if (BNXT_PF(softc) && 1141 (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_VF_CFG_ASYNC_FOR_PF_SUPPORTED)) 1142 softc->fw_cap |= BNXT_FW_CAP_VF_CFG_FOR_PF; 1143 1144 flags_ext2 = htole32(resp->flags_ext2); 1145 if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_RX_ALL_PKTS_TIMESTAMPS_SUPPORTED) 1146 softc->fw_cap |= BNXT_FW_CAP_RX_ALL_PKT_TS; 1147 if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_SW_DBR_DROP_RECOVERY_SUPPORTED) 1148 softc->fw_cap |= BNXT_FW_CAP_DBR_SUPPORTED; 1149 if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_DBR_PACING_EXT_SUPPORTED || 1150 flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_DBR_PACING_SUPPORTED) 1151 softc->fw_cap |= BNXT_FW_CAP_DBR_PACING_SUPPORTED; 1152 1153 if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_GENERIC_STATS_SUPPORTED) 1154 softc->fw_cap |= BNXT_FW_CAP_GENERIC_STATS; 1155 func->fw_fid = le16toh(resp->fid); 1156 memcpy(func->mac_addr, resp->mac_address, ETHER_ADDR_LEN); 1157 func->max_rsscos_ctxs = le16toh(resp->max_rsscos_ctx); 1158 func->max_cp_rings = le16toh(resp->max_cmpl_rings); 1159 func->max_tx_rings = le16toh(resp->max_tx_rings); 1160 func->max_rx_rings = le16toh(resp->max_rx_rings); 1161 func->max_hw_ring_grps = le32toh(resp->max_hw_ring_grps); 1162 if (!func->max_hw_ring_grps) 1163 func->max_hw_ring_grps = func->max_tx_rings; 1164 func->max_l2_ctxs = le16toh(resp->max_l2_ctxs); 1165 func->max_vnics = le16toh(resp->max_vnics); 1166 func->max_stat_ctxs = le16toh(resp->max_stat_ctx); 1167 if (BNXT_PF(softc)) { 1168 struct bnxt_pf_info *pf = &softc->pf; 1169 1170 pf->port_id = le16toh(resp->port_id); 1171 pf->first_vf_id = le16toh(resp->first_vf_id); 1172 pf->max_vfs = le16toh(resp->max_vfs); 1173 pf->max_encap_records = le32toh(resp->max_encap_records); 1174 pf->max_decap_records = le32toh(resp->max_decap_records); 1175 pf->max_tx_em_flows = le32toh(resp->max_tx_em_flows); 1176 pf->max_tx_wm_flows = le32toh(resp->max_tx_wm_flows); 1177 pf->max_rx_em_flows = le32toh(resp->max_rx_em_flows); 1178 pf->max_rx_wm_flows = le32toh(resp->max_rx_wm_flows); 1179 } 1180 if (!_is_valid_ether_addr(func->mac_addr)) { 1181 device_printf(softc->dev, "Invalid ethernet address, generating random locally administered address\n"); 1182 get_random_ether_addr(func->mac_addr); 1183 } 1184 1185 fail: 1186 BNXT_HWRM_UNLOCK(softc); 1187 return rc; 1188 } 1189 1190 int 1191 bnxt_hwrm_func_qcfg(struct bnxt_softc *softc) 1192 { 1193 struct hwrm_func_qcfg_input req = {0}; 1194 struct hwrm_func_qcfg_output *resp = 1195 (void *)softc->hwrm_cmd_resp.idi_vaddr; 1196 struct bnxt_func_qcfg *fn_qcfg = &softc->fn_qcfg; 1197 uint32_t min_db_offset = 0; 1198 uint16_t flags; 1199 int rc; 1200 1201 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_QCFG); 1202 req.fid = htole16(0xffff); 1203 BNXT_HWRM_LOCK(softc); 1204 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1205 if (rc) 1206 goto end; 1207 1208 fn_qcfg->alloc_completion_rings = le16toh(resp->alloc_cmpl_rings); 1209 fn_qcfg->alloc_tx_rings = le16toh(resp->alloc_tx_rings); 1210 fn_qcfg->alloc_rx_rings = le16toh(resp->alloc_rx_rings); 1211 fn_qcfg->alloc_vnics = le16toh(resp->alloc_vnics); 1212 1213 switch (resp->port_partition_type) { 1214 case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0: 1215 case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_2: 1216 case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5: 1217 case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0: 1218 softc->port_partition_type = resp->port_partition_type; 1219 break; 1220 } 1221 1222 flags = le16toh(resp->flags); 1223 if (flags & (HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED | 1224 HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_LLDP_AGENT_ENABLED)) { 1225 softc->fw_cap |= BNXT_FW_CAP_LLDP_AGENT; 1226 if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED) 1227 softc->fw_cap |= BNXT_FW_CAP_DCBX_AGENT; 1228 } 1229 if (BNXT_PF(softc) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST)) 1230 softc->flags |= BNXT_FLAG_MULTI_HOST; 1231 if (BNXT_PF(softc) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_ROOT)) 1232 softc->flags |= BNXT_FLAG_MULTI_ROOT; 1233 if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_SECURE_MODE_ENABLED) 1234 softc->fw_cap |= BNXT_FW_CAP_SECURE_MODE; 1235 if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_RING_MONITOR_ENABLED) 1236 softc->fw_cap |= BNXT_FW_CAP_RING_MONITOR; 1237 if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_ENABLE_RDMA_SRIOV) 1238 softc->fw_cap |= BNXT_FW_CAP_ENABLE_RDMA_SRIOV; 1239 1240 if (softc->db_size) 1241 goto end; 1242 1243 softc->legacy_db_size = le16_to_cpu(resp->legacy_l2_db_size_kb) * 1024; 1244 1245 if (BNXT_CHIP_P5(softc)) { 1246 if (BNXT_PF(softc)) 1247 min_db_offset = DB_PF_OFFSET_P5; 1248 else 1249 min_db_offset = DB_VF_OFFSET_P5; 1250 } 1251 1252 softc->db_size = roundup2(le16_to_cpu(resp->l2_doorbell_bar_size_kb) * 1253 1024, PAGE_SIZE); 1254 if (!softc->db_size || softc->db_size > pci_resource_len(softc->pdev, 2) || 1255 softc->db_size <= min_db_offset) 1256 softc->db_size = pci_resource_len(softc->pdev, 2); 1257 1258 end: 1259 BNXT_HWRM_UNLOCK(softc); 1260 return rc; 1261 } 1262 1263 int 1264 bnxt_hwrm_func_reset(struct bnxt_softc *softc) 1265 { 1266 struct hwrm_func_reset_input req = {0}; 1267 1268 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_RESET); 1269 req.enables = 0; 1270 1271 return hwrm_send_message(softc, &req, sizeof(req)); 1272 } 1273 1274 static void 1275 bnxt_hwrm_set_link_common(struct bnxt_softc *softc, 1276 struct hwrm_port_phy_cfg_input *req) 1277 { 1278 struct bnxt_link_info *link_info = &softc->link_info; 1279 uint8_t autoneg = softc->link_info.autoneg; 1280 uint16_t fw_link_speed = softc->link_info.req_link_speed; 1281 1282 if (autoneg & BNXT_AUTONEG_SPEED) { 1283 uint8_t phy_type = get_phy_type(softc); 1284 1285 if (phy_type == HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASET || 1286 phy_type == HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET || 1287 phy_type == HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE) { 1288 1289 req->auto_mode |= htole32(HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK); 1290 if (link_info->advertising) { 1291 req->enables |= htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK); 1292 req->auto_link_speed_mask = htole16(link_info->advertising); 1293 } 1294 } else { 1295 req->auto_mode |= HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS; 1296 } 1297 1298 req->enables |= 1299 htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE); 1300 req->flags |= 1301 htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG); 1302 } else { 1303 req->flags |= htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE); 1304 1305 if (link_info->force_pam4_speed_set_by_user) { 1306 req->force_pam4_link_speed = htole16(fw_link_speed); 1307 req->enables |= htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAM4_LINK_SPEED); 1308 link_info->force_pam4_speed_set_by_user = false; 1309 } else { 1310 req->force_link_speed = htole16(fw_link_speed); 1311 } 1312 } 1313 1314 /* tell chimp that the setting takes effect immediately */ 1315 req->flags |= htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY); 1316 } 1317 1318 static void 1319 bnxt_hwrm_set_pause_common(struct bnxt_softc *softc, 1320 struct hwrm_port_phy_cfg_input *req) 1321 { 1322 struct bnxt_link_info *link_info = &softc->link_info; 1323 1324 if (link_info->flow_ctrl.autoneg) { 1325 req->auto_pause = 1326 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE; 1327 if (link_info->flow_ctrl.rx) 1328 req->auto_pause |= 1329 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX; 1330 if (link_info->flow_ctrl.tx) 1331 req->auto_pause |= 1332 HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX; 1333 req->enables |= 1334 htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE); 1335 } else { 1336 if (link_info->flow_ctrl.rx) 1337 req->force_pause |= 1338 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX; 1339 if (link_info->flow_ctrl.tx) 1340 req->force_pause |= 1341 HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX; 1342 req->enables |= 1343 htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE); 1344 req->auto_pause = req->force_pause; 1345 req->enables |= 1346 htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE); 1347 } 1348 } 1349 1350 /* JFV this needs interface connection */ 1351 static void 1352 bnxt_hwrm_set_eee(struct bnxt_softc *softc, struct hwrm_port_phy_cfg_input *req) 1353 { 1354 /* struct ethtool_eee *eee = &softc->eee; */ 1355 bool eee_enabled = false; 1356 1357 if (eee_enabled) { 1358 #if 0 1359 uint16_t eee_speeds; 1360 uint32_t flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_ENABLE; 1361 1362 if (eee->tx_lpi_enabled) 1363 flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI; 1364 1365 req->flags |= htole32(flags); 1366 eee_speeds = bnxt_get_fw_auto_link_speeds(eee->advertised); 1367 req->eee_link_speed_mask = htole16(eee_speeds); 1368 req->tx_lpi_timer = htole32(eee->tx_lpi_timer); 1369 #endif 1370 } else { 1371 req->flags |= 1372 htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_DISABLE); 1373 } 1374 } 1375 1376 int 1377 bnxt_hwrm_set_link_setting(struct bnxt_softc *softc, bool set_pause, 1378 bool set_eee, bool set_link) 1379 { 1380 struct hwrm_port_phy_cfg_input req = {0}; 1381 int rc; 1382 1383 if (softc->flags & BNXT_FLAG_NPAR) 1384 return ENOTSUP; 1385 1386 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_CFG); 1387 1388 if (set_pause) { 1389 bnxt_hwrm_set_pause_common(softc, &req); 1390 1391 if (softc->link_info.flow_ctrl.autoneg) 1392 set_link = true; 1393 } 1394 1395 if (set_link) 1396 bnxt_hwrm_set_link_common(softc, &req); 1397 1398 if (set_eee) 1399 bnxt_hwrm_set_eee(softc, &req); 1400 1401 BNXT_HWRM_LOCK(softc); 1402 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1403 1404 if (!rc) { 1405 if (set_pause) { 1406 /* since changing of 'force pause' setting doesn't 1407 * trigger any link change event, the driver needs to 1408 * update the current pause result upon successfully i 1409 * return of the phy_cfg command */ 1410 if (!softc->link_info.flow_ctrl.autoneg) 1411 bnxt_report_link(softc); 1412 } 1413 } 1414 BNXT_HWRM_UNLOCK(softc); 1415 return rc; 1416 } 1417 1418 int 1419 bnxt_hwrm_vnic_set_hds(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic) 1420 { 1421 struct hwrm_vnic_plcmodes_cfg_input req = {0}; 1422 1423 if (!BNXT_CHIP_P5(softc)) 1424 return 0; 1425 1426 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_PLCMODES_CFG); 1427 1428 req.flags = htole32(HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT); 1429 req.vnic_id = htole16(vnic->id); 1430 1431 return hwrm_send_message(softc, &req, sizeof(req)); 1432 } 1433 1434 int 1435 bnxt_hwrm_vnic_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic) 1436 { 1437 struct hwrm_vnic_cfg_input req = {0}; 1438 1439 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_CFG); 1440 1441 if (vnic->flags & BNXT_VNIC_FLAG_DEFAULT) 1442 req.flags |= htole32(HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT); 1443 if (vnic->flags & BNXT_VNIC_FLAG_BD_STALL) 1444 req.flags |= htole32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE); 1445 if (vnic->flags & BNXT_VNIC_FLAG_VLAN_STRIP) 1446 req.flags |= htole32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE); 1447 if (BNXT_CHIP_P5 (softc)) { 1448 req.default_rx_ring_id = 1449 htole16(softc->rx_rings[0].phys_id); 1450 req.default_cmpl_ring_id = 1451 htole16(softc->rx_cp_rings[0].ring.phys_id); 1452 req.enables |= 1453 htole32(HWRM_VNIC_CFG_INPUT_ENABLES_DEFAULT_RX_RING_ID | 1454 HWRM_VNIC_CFG_INPUT_ENABLES_DEFAULT_CMPL_RING_ID); 1455 req.vnic_id = htole16(vnic->id); 1456 } else { 1457 req.enables = htole32(HWRM_VNIC_CFG_INPUT_ENABLES_DFLT_RING_GRP | 1458 HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE); 1459 req.vnic_id = htole16(vnic->id); 1460 req.dflt_ring_grp = htole16(vnic->def_ring_grp); 1461 } 1462 req.rss_rule = htole16(vnic->rss_id); 1463 req.cos_rule = htole16(vnic->cos_rule); 1464 req.lb_rule = htole16(vnic->lb_rule); 1465 req.enables |= htole32(HWRM_VNIC_CFG_INPUT_ENABLES_MRU); 1466 req.mru = htole16(vnic->mru); 1467 1468 return hwrm_send_message(softc, &req, sizeof(req)); 1469 } 1470 1471 int 1472 bnxt_hwrm_vnic_free(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic) 1473 { 1474 struct hwrm_vnic_free_input req = {0}; 1475 int rc = 0; 1476 1477 if (vnic->id == (uint16_t)HWRM_NA_SIGNATURE) 1478 return rc; 1479 1480 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_FREE); 1481 1482 req.vnic_id = htole32(vnic->id); 1483 1484 BNXT_HWRM_LOCK(softc); 1485 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1486 if (rc) 1487 goto fail; 1488 1489 fail: 1490 BNXT_HWRM_UNLOCK(softc); 1491 return (rc); 1492 } 1493 1494 int 1495 bnxt_hwrm_vnic_alloc(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic) 1496 { 1497 struct hwrm_vnic_alloc_input req = {0}; 1498 struct hwrm_vnic_alloc_output *resp = 1499 (void *)softc->hwrm_cmd_resp.idi_vaddr; 1500 int rc; 1501 1502 if (vnic->id != (uint16_t)HWRM_NA_SIGNATURE) { 1503 device_printf(softc->dev, 1504 "Attempt to re-allocate vnic %04x\n", vnic->id); 1505 return EDOOFUS; 1506 } 1507 1508 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_ALLOC); 1509 1510 if (vnic->flags & BNXT_VNIC_FLAG_DEFAULT) 1511 req.flags = htole32(HWRM_VNIC_ALLOC_INPUT_FLAGS_DEFAULT); 1512 1513 BNXT_HWRM_LOCK(softc); 1514 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1515 if (rc) 1516 goto fail; 1517 1518 vnic->id = le32toh(resp->vnic_id); 1519 1520 fail: 1521 BNXT_HWRM_UNLOCK(softc); 1522 return (rc); 1523 } 1524 1525 int 1526 bnxt_hwrm_vnic_ctx_free(struct bnxt_softc *softc, uint16_t ctx_id) 1527 { 1528 struct hwrm_vnic_rss_cos_lb_ctx_free_input req = {0}; 1529 int rc = 0; 1530 1531 if (ctx_id == (uint16_t)HWRM_NA_SIGNATURE) 1532 return rc; 1533 1534 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_RSS_COS_LB_CTX_FREE); 1535 req.rss_cos_lb_ctx_id = htole16(ctx_id); 1536 BNXT_HWRM_LOCK(softc); 1537 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1538 if (rc) 1539 goto fail; 1540 1541 fail: 1542 BNXT_HWRM_UNLOCK(softc); 1543 return rc; 1544 } 1545 1546 int 1547 bnxt_hwrm_vnic_ctx_alloc(struct bnxt_softc *softc, uint16_t *ctx_id) 1548 { 1549 struct hwrm_vnic_rss_cos_lb_ctx_alloc_input req = {0}; 1550 struct hwrm_vnic_rss_cos_lb_ctx_alloc_output *resp = 1551 (void *)softc->hwrm_cmd_resp.idi_vaddr; 1552 int rc; 1553 1554 if (*ctx_id != (uint16_t)HWRM_NA_SIGNATURE) { 1555 device_printf(softc->dev, 1556 "Attempt to re-allocate vnic ctx %04x\n", *ctx_id); 1557 return EDOOFUS; 1558 } 1559 1560 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_RSS_COS_LB_CTX_ALLOC); 1561 1562 BNXT_HWRM_LOCK(softc); 1563 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1564 if (rc) 1565 goto fail; 1566 1567 *ctx_id = le32toh(resp->rss_cos_lb_ctx_id); 1568 1569 fail: 1570 BNXT_HWRM_UNLOCK(softc); 1571 return (rc); 1572 } 1573 1574 int 1575 bnxt_hwrm_ring_grp_alloc(struct bnxt_softc *softc, struct bnxt_grp_info *grp) 1576 { 1577 struct hwrm_ring_grp_alloc_input req = {0}; 1578 struct hwrm_ring_grp_alloc_output *resp; 1579 int rc = 0; 1580 1581 if (grp->grp_id != (uint16_t)HWRM_NA_SIGNATURE) { 1582 device_printf(softc->dev, 1583 "Attempt to re-allocate ring group %04x\n", grp->grp_id); 1584 return EDOOFUS; 1585 } 1586 1587 if (BNXT_CHIP_P5 (softc)) 1588 return 0; 1589 1590 resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; 1591 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_GRP_ALLOC); 1592 req.cr = htole16(grp->cp_ring_id); 1593 req.rr = htole16(grp->rx_ring_id); 1594 req.ar = htole16(grp->ag_ring_id); 1595 req.sc = htole16(grp->stats_ctx); 1596 1597 BNXT_HWRM_LOCK(softc); 1598 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1599 if (rc) 1600 goto fail; 1601 1602 grp->grp_id = le32toh(resp->ring_group_id); 1603 1604 fail: 1605 BNXT_HWRM_UNLOCK(softc); 1606 return rc; 1607 } 1608 1609 int 1610 bnxt_hwrm_ring_grp_free(struct bnxt_softc *softc, struct bnxt_grp_info *grp) 1611 { 1612 struct hwrm_ring_grp_free_input req = {0}; 1613 int rc = 0; 1614 1615 if (grp->grp_id == (uint16_t)HWRM_NA_SIGNATURE) 1616 return 0; 1617 1618 if (BNXT_CHIP_P5 (softc)) 1619 return 0; 1620 1621 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_GRP_FREE); 1622 1623 req.ring_group_id = htole32(grp->grp_id); 1624 1625 BNXT_HWRM_LOCK(softc); 1626 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1627 if (rc) 1628 goto fail; 1629 1630 fail: 1631 BNXT_HWRM_UNLOCK(softc); 1632 return rc; 1633 } 1634 1635 int bnxt_hwrm_ring_free(struct bnxt_softc *softc, uint32_t ring_type, 1636 struct bnxt_ring *ring, int cmpl_ring_id) 1637 { 1638 struct hwrm_ring_free_input req = {0}; 1639 struct hwrm_ring_free_output *resp; 1640 int rc = 0; 1641 uint16_t error_code; 1642 1643 if (ring->phys_id == (uint16_t)HWRM_NA_SIGNATURE) 1644 return 0; 1645 1646 resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; 1647 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_FREE); 1648 req.cmpl_ring = htole16(cmpl_ring_id); 1649 req.ring_type = ring_type; 1650 req.ring_id = htole16(ring->phys_id); 1651 1652 BNXT_HWRM_LOCK(softc); 1653 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1654 error_code = le16toh(resp->error_code); 1655 1656 if (rc || error_code) { 1657 device_printf(softc->dev, "hwrm_ring_free type %d failed. " 1658 "rc:%x err:%x\n", ring_type, rc, error_code); 1659 if (!rc) 1660 rc = -EIO; 1661 } 1662 1663 BNXT_HWRM_UNLOCK(softc); 1664 return rc; 1665 } 1666 1667 /* 1668 * Ring allocation message to the firmware 1669 */ 1670 int 1671 bnxt_hwrm_ring_alloc(struct bnxt_softc *softc, uint8_t type, 1672 struct bnxt_ring *ring) 1673 { 1674 struct hwrm_ring_alloc_input req = {0}; 1675 struct hwrm_ring_alloc_output *resp; 1676 uint16_t idx = ring->idx; 1677 struct bnxt_cp_ring *cp_ring; 1678 int rc; 1679 1680 if (ring->phys_id != (uint16_t)HWRM_NA_SIGNATURE) { 1681 device_printf(softc->dev, 1682 "Attempt to re-allocate ring %04x\n", ring->phys_id); 1683 return EDOOFUS; 1684 } 1685 1686 resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; 1687 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_ALLOC); 1688 req.enables = htole32(0); 1689 req.fbo = htole32(0); 1690 req.ring_type = type; 1691 req.page_tbl_addr = htole64(ring->paddr); 1692 req.logical_id = htole16(ring->id); 1693 req.length = htole32(ring->ring_size); 1694 1695 switch (type) { 1696 case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX: 1697 cp_ring = &softc->tx_cp_rings[idx]; 1698 1699 req.cmpl_ring_id = htole16(cp_ring->ring.phys_id); 1700 /* queue_id - what CoS queue the TX ring is associated with */ 1701 req.queue_id = htole16(softc->tx_q_info[0].queue_id); 1702 1703 req.stat_ctx_id = htole32(cp_ring->stats_ctx_id); 1704 req.enables |= htole32( 1705 HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID); 1706 break; 1707 case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX: 1708 if (!BNXT_CHIP_P5(softc)) 1709 break; 1710 1711 cp_ring = &softc->rx_cp_rings[idx]; 1712 1713 req.stat_ctx_id = htole32(cp_ring->stats_ctx_id); 1714 req.rx_buf_size = htole16(softc->rx_buf_size); 1715 req.enables |= htole32( 1716 HWRM_RING_ALLOC_INPUT_ENABLES_RX_BUF_SIZE_VALID | 1717 HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID); 1718 break; 1719 case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX_AGG: 1720 if (!BNXT_CHIP_P5(softc)) { 1721 req.ring_type = HWRM_RING_ALLOC_INPUT_RING_TYPE_RX; 1722 break; 1723 } 1724 1725 cp_ring = &softc->rx_cp_rings[idx]; 1726 1727 req.rx_ring_id = htole16(softc->rx_rings[idx].phys_id); 1728 req.stat_ctx_id = htole32(cp_ring->stats_ctx_id); 1729 req.rx_buf_size = htole16(softc->rx_buf_size); 1730 req.enables |= htole32( 1731 HWRM_RING_ALLOC_INPUT_ENABLES_RX_RING_ID_VALID | 1732 HWRM_RING_ALLOC_INPUT_ENABLES_RX_BUF_SIZE_VALID | 1733 HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID); 1734 break; 1735 case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL: 1736 if (!BNXT_CHIP_P5(softc)) { 1737 req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX; 1738 break; 1739 } 1740 1741 req.cq_handle = htole64(ring->id); 1742 req.nq_ring_id = htole16(softc->nq_rings[idx].ring.phys_id); 1743 req.enables |= htole32( 1744 HWRM_RING_ALLOC_INPUT_ENABLES_NQ_RING_ID_VALID); 1745 break; 1746 case HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ: 1747 req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX; 1748 break; 1749 default: 1750 device_printf(softc->dev, 1751 "hwrm alloc invalid ring type %d\n", type); 1752 return -1; 1753 } 1754 1755 BNXT_HWRM_LOCK(softc); 1756 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1757 if (rc) 1758 goto fail; 1759 1760 ring->phys_id = le16toh(resp->ring_id); 1761 1762 fail: 1763 BNXT_HWRM_UNLOCK(softc); 1764 return rc; 1765 } 1766 1767 int 1768 bnxt_hwrm_stat_ctx_free(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr) 1769 { 1770 struct hwrm_stat_ctx_free_input req = {0}; 1771 int rc = 0; 1772 1773 if (cpr->stats_ctx_id == HWRM_NA_SIGNATURE) 1774 return rc; 1775 1776 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_STAT_CTX_FREE); 1777 1778 req.stat_ctx_id = htole16(cpr->stats_ctx_id); 1779 BNXT_HWRM_LOCK(softc); 1780 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1781 if (rc) 1782 goto fail; 1783 1784 fail: 1785 BNXT_HWRM_UNLOCK(softc); 1786 1787 return rc; 1788 } 1789 1790 int 1791 bnxt_hwrm_stat_ctx_alloc(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr, 1792 uint64_t paddr) 1793 { 1794 struct hwrm_stat_ctx_alloc_input req = {0}; 1795 struct hwrm_stat_ctx_alloc_output *resp; 1796 int rc = 0; 1797 1798 if (cpr->stats_ctx_id != HWRM_NA_SIGNATURE) { 1799 device_printf(softc->dev, 1800 "Attempt to re-allocate stats ctx %08x\n", 1801 cpr->stats_ctx_id); 1802 return EDOOFUS; 1803 } 1804 1805 resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; 1806 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_STAT_CTX_ALLOC); 1807 1808 req.update_period_ms = htole32(1000); 1809 req.stats_dma_addr = htole64(paddr); 1810 if (BNXT_CHIP_P5(softc)) 1811 req.stats_dma_length = htole16(sizeof(struct ctx_hw_stats_ext) - 8); 1812 else 1813 req.stats_dma_length = htole16(sizeof(struct ctx_hw_stats)); 1814 1815 BNXT_HWRM_LOCK(softc); 1816 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1817 if (rc) 1818 goto fail; 1819 1820 cpr->stats_ctx_id = le32toh(resp->stat_ctx_id); 1821 1822 fail: 1823 BNXT_HWRM_UNLOCK(softc); 1824 1825 return rc; 1826 } 1827 1828 int 1829 bnxt_hwrm_port_qstats(struct bnxt_softc *softc) 1830 { 1831 struct hwrm_port_qstats_input req = {0}; 1832 int rc = 0; 1833 1834 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_QSTATS); 1835 1836 req.port_id = htole16(softc->pf.port_id); 1837 req.rx_stat_host_addr = htole64(softc->hw_rx_port_stats.idi_paddr); 1838 req.tx_stat_host_addr = htole64(softc->hw_tx_port_stats.idi_paddr); 1839 1840 BNXT_HWRM_LOCK(softc); 1841 rc = _hwrm_send_message(softc, &req, sizeof(req)); 1842 BNXT_HWRM_UNLOCK(softc); 1843 1844 return rc; 1845 } 1846 static int bnxt_hwrm_pri2cos_idx(struct bnxt_softc *softc, uint32_t path_dir) 1847 { 1848 struct hwrm_queue_pri2cos_qcfg_input req = {0}; 1849 struct hwrm_queue_pri2cos_qcfg_output *resp; 1850 uint8_t *pri2cos_idx, *q_ids, max_q; 1851 int rc, i, j; 1852 uint8_t *pri2cos; 1853 1854 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_PRI2COS_QCFG); 1855 resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; 1856 1857 req.flags = htole32(HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_IVLAN | 1858 path_dir); 1859 rc = hwrm_send_message(softc, &req, sizeof(req)); 1860 1861 if (rc) 1862 return rc; 1863 1864 if (path_dir == HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_TX) { 1865 pri2cos_idx = softc->tx_pri2cos_idx; 1866 q_ids = softc->tx_q_ids; 1867 max_q = softc->tx_max_q; 1868 } else { 1869 pri2cos_idx = softc->rx_pri2cos_idx; 1870 q_ids = softc->rx_q_ids; 1871 max_q = softc->rx_max_q; 1872 } 1873 1874 pri2cos = &resp->pri0_cos_queue_id; 1875 1876 for (i = 0; i < BNXT_MAX_QUEUE; i++) { 1877 uint8_t queue_id = pri2cos[i]; 1878 uint8_t queue_idx; 1879 1880 /* Per port queue IDs start from 0, 10, 20, etc */ 1881 queue_idx = queue_id % 10; 1882 if (queue_idx > BNXT_MAX_QUEUE) { 1883 softc->pri2cos_valid = false; 1884 rc = -EINVAL; 1885 return rc; 1886 } 1887 1888 for (j = 0; j < max_q; j++) { 1889 if (q_ids[j] == queue_id) 1890 pri2cos_idx[i] = queue_idx; 1891 } 1892 } 1893 1894 softc->pri2cos_valid = true; 1895 1896 return rc; 1897 } 1898 1899 int 1900 bnxt_hwrm_port_qstats_ext(struct bnxt_softc *softc) 1901 { 1902 struct hwrm_port_qstats_ext_input req = {0}; 1903 struct hwrm_port_qstats_ext_output *resp; 1904 int rc = 0, i; 1905 uint32_t tx_stat_size; 1906 1907 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_QSTATS_EXT); 1908 resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; 1909 1910 tx_stat_size = sizeof(struct tx_port_stats_ext); 1911 req.port_id = htole16(softc->pf.port_id); 1912 req.tx_stat_size = htole16(tx_stat_size); 1913 req.rx_stat_size = htole16(sizeof(struct rx_port_stats_ext)); 1914 req.rx_stat_host_addr = htole64(softc->hw_rx_port_stats_ext.idi_paddr); 1915 req.tx_stat_host_addr = htole64(softc->hw_tx_port_stats_ext.idi_paddr); 1916 1917 rc = hwrm_send_message(softc, &req, sizeof(req)); 1918 1919 if (!rc) { 1920 softc->fw_rx_stats_ext_size = 1921 le16toh(resp->rx_stat_size) / 8; 1922 if (BNXT_FW_MAJ(softc) < 220 && 1923 softc->fw_rx_stats_ext_size > BNXT_RX_STATS_EXT_NUM_LEGACY) 1924 softc->fw_rx_stats_ext_size = BNXT_RX_STATS_EXT_NUM_LEGACY; 1925 1926 softc->fw_tx_stats_ext_size = tx_stat_size ? 1927 le16toh(resp->tx_stat_size) / 8 : 0; 1928 } else { 1929 softc->fw_rx_stats_ext_size = 0; 1930 softc->fw_tx_stats_ext_size = 0; 1931 } 1932 1933 if (softc->fw_tx_stats_ext_size <= 1934 offsetof(struct tx_port_stats_ext, pfc_pri0_tx_duration_us) / 8) { 1935 softc->pri2cos_valid = false; 1936 return rc; 1937 } 1938 1939 rc = bnxt_hwrm_pri2cos_idx(softc, HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_TX); 1940 if (rc) 1941 return rc; 1942 1943 if (softc->is_asym_q) { 1944 rc = bnxt_hwrm_pri2cos_idx(softc, HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_RX); 1945 if (rc) 1946 return rc; 1947 } else { 1948 memcpy(softc->rx_pri2cos_idx, softc->tx_pri2cos_idx, sizeof(softc->rx_pri2cos_idx)); 1949 } 1950 1951 u64 *rx_port_stats_ext = (u64 *)softc->hw_rx_port_stats_ext.idi_vaddr; 1952 u64 *tx_port_stats_ext = (u64 *)softc->hw_tx_port_stats_ext.idi_vaddr; 1953 1954 if (softc->pri2cos_valid) { 1955 for (i = 0; i < 8; i++) { 1956 long n = bnxt_rx_bytes_pri_arr_base_off[i] + 1957 softc->rx_pri2cos_idx[i]; 1958 1959 softc->rx_bytes_pri[i] = *(rx_port_stats_ext + n); 1960 } 1961 for (i = 0; i < 8; i++) { 1962 long n = bnxt_rx_pkts_pri_arr_base_off[i] + 1963 softc->rx_pri2cos_idx[i]; 1964 1965 softc->rx_packets_pri[i] = *(rx_port_stats_ext + n); 1966 } 1967 for (i = 0; i < 8; i++) { 1968 long n = bnxt_tx_bytes_pri_arr_base_off[i] + 1969 softc->tx_pri2cos_idx[i]; 1970 1971 softc->tx_bytes_pri[i] = *(tx_port_stats_ext + n); 1972 } 1973 for (i = 0; i < 8; i++) { 1974 long n = bnxt_tx_pkts_pri_arr_base_off[i] + 1975 softc->tx_pri2cos_idx[i]; 1976 1977 softc->tx_packets_pri[i] = *(tx_port_stats_ext + n); 1978 } 1979 } 1980 1981 return rc; 1982 } 1983 1984 int 1985 bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt_softc *softc, 1986 struct bnxt_vnic_info *vnic) 1987 { 1988 struct hwrm_cfa_l2_set_rx_mask_input req = {0}; 1989 uint32_t mask = vnic->rx_mask; 1990 1991 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_SET_RX_MASK); 1992 1993 req.vnic_id = htole32(vnic->id); 1994 req.mask = htole32(mask); 1995 req.mc_tbl_addr = htole64(vnic->mc_list.idi_paddr); 1996 req.num_mc_entries = htole32(vnic->mc_list_count); 1997 return hwrm_send_message(softc, &req, sizeof(req)); 1998 } 1999 2000 int 2001 bnxt_hwrm_l2_filter_free(struct bnxt_softc *softc, uint64_t filter_id) 2002 { 2003 struct hwrm_cfa_l2_filter_free_input req = {0}; 2004 int rc = 0; 2005 2006 if (filter_id == -1) 2007 return rc; 2008 2009 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_FILTER_FREE); 2010 2011 req.l2_filter_id = htole64(filter_id); 2012 2013 BNXT_HWRM_LOCK(softc); 2014 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2015 if (rc) 2016 goto fail; 2017 2018 fail: 2019 BNXT_HWRM_UNLOCK(softc); 2020 return (rc); 2021 } 2022 2023 int 2024 bnxt_hwrm_free_filter(struct bnxt_softc *softc) 2025 { 2026 struct bnxt_vnic_info *vnic = &softc->vnic_info; 2027 struct bnxt_vlan_tag *tag; 2028 int rc = 0; 2029 2030 rc = bnxt_hwrm_l2_filter_free(softc, softc->vnic_info.filter_id); 2031 if (rc) 2032 goto end; 2033 2034 SLIST_FOREACH(tag, &vnic->vlan_tags, next) { 2035 rc = bnxt_hwrm_l2_filter_free(softc, tag->filter_id); 2036 if (rc) 2037 goto end; 2038 tag->filter_id = -1; 2039 } 2040 2041 end: 2042 return rc; 2043 } 2044 2045 int 2046 bnxt_hwrm_l2_filter_alloc(struct bnxt_softc *softc, uint16_t vlan_tag, 2047 uint64_t *filter_id) 2048 { 2049 struct hwrm_cfa_l2_filter_alloc_input req = {0}; 2050 struct hwrm_cfa_l2_filter_alloc_output *resp; 2051 struct bnxt_vnic_info *vnic = &softc->vnic_info; 2052 uint32_t enables = 0; 2053 int rc = 0; 2054 2055 if (*filter_id != -1) { 2056 device_printf(softc->dev, "Attempt to re-allocate l2 ctx " 2057 "filter (fid: 0x%jx)\n", (uintmax_t)*filter_id); 2058 return EDOOFUS; 2059 } 2060 2061 resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; 2062 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_CFA_L2_FILTER_ALLOC); 2063 2064 req.flags = htole32(HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX); 2065 enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR 2066 | HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK 2067 | HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID; 2068 2069 if (vlan_tag != 0xffff) { 2070 enables |= 2071 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN | 2072 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK | 2073 HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_NUM_VLANS; 2074 req.l2_ivlan_mask = 0xffff; 2075 req.l2_ivlan = vlan_tag; 2076 req.num_vlans = 1; 2077 } 2078 2079 req.enables = htole32(enables); 2080 req.dst_id = htole16(vnic->id); 2081 memcpy(req.l2_addr, if_getlladdr(iflib_get_ifp(softc->ctx)), 2082 ETHER_ADDR_LEN); 2083 memset(&req.l2_addr_mask, 0xff, sizeof(req.l2_addr_mask)); 2084 2085 BNXT_HWRM_LOCK(softc); 2086 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2087 if (rc) 2088 goto fail; 2089 2090 *filter_id = le64toh(resp->l2_filter_id); 2091 fail: 2092 BNXT_HWRM_UNLOCK(softc); 2093 return (rc); 2094 } 2095 2096 int 2097 bnxt_hwrm_set_filter(struct bnxt_softc *softc) 2098 { 2099 struct bnxt_vnic_info *vnic = &softc->vnic_info; 2100 struct bnxt_vlan_tag *tag; 2101 int rc = 0; 2102 2103 rc = bnxt_hwrm_l2_filter_alloc(softc, 0xffff, &vnic->filter_id); 2104 if (rc) 2105 goto end; 2106 2107 SLIST_FOREACH(tag, &vnic->vlan_tags, next) { 2108 rc = bnxt_hwrm_l2_filter_alloc(softc, tag->tag, 2109 &tag->filter_id); 2110 if (rc) 2111 goto end; 2112 } 2113 2114 end: 2115 return rc; 2116 } 2117 2118 int 2119 bnxt_hwrm_rss_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic, 2120 uint32_t hash_type) 2121 { 2122 struct hwrm_vnic_rss_cfg_input req = {0}; 2123 2124 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_RSS_CFG); 2125 2126 req.hash_type = htole32(hash_type); 2127 req.ring_grp_tbl_addr = htole64(vnic->rss_grp_tbl.idi_paddr); 2128 req.hash_key_tbl_addr = htole64(vnic->rss_hash_key_tbl.idi_paddr); 2129 req.rss_ctx_idx = htole16(vnic->rss_id); 2130 req.hash_mode_flags = HWRM_FUNC_SPD_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT; 2131 if (BNXT_CHIP_P5(softc)) { 2132 req.vnic_id = htole16(vnic->id); 2133 req.ring_table_pair_index = 0x0; 2134 } 2135 2136 return hwrm_send_message(softc, &req, sizeof(req)); 2137 } 2138 2139 int 2140 bnxt_hwrm_reserve_pf_rings(struct bnxt_softc *softc) 2141 { 2142 struct hwrm_func_cfg_input req = {0}; 2143 2144 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG); 2145 2146 req.fid = htole16(0xffff); 2147 req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS); 2148 req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS); 2149 req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS); 2150 req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS); 2151 req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS); 2152 req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_MSIX); 2153 req.enables |= htole32(HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS); 2154 req.num_msix = htole16(BNXT_MAX_NUM_QUEUES); 2155 req.num_rsscos_ctxs = htole16(0x8); 2156 req.num_cmpl_rings = htole16(BNXT_MAX_NUM_QUEUES * 2); 2157 req.num_tx_rings = htole16(BNXT_MAX_NUM_QUEUES); 2158 req.num_rx_rings = htole16(BNXT_MAX_NUM_QUEUES); 2159 req.num_vnics = htole16(BNXT_MAX_NUM_QUEUES); 2160 req.num_stat_ctxs = htole16(BNXT_MAX_NUM_QUEUES * 2); 2161 2162 return hwrm_send_message(softc, &req, sizeof(req)); 2163 } 2164 2165 int 2166 bnxt_cfg_async_cr(struct bnxt_softc *softc) 2167 { 2168 int rc = 0; 2169 struct hwrm_func_cfg_input req = {0}; 2170 2171 if (!BNXT_PF(softc)) 2172 return 0; 2173 2174 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG); 2175 2176 req.fid = htole16(0xffff); 2177 req.enables = htole32(HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR); 2178 if (BNXT_CHIP_P5(softc)) 2179 req.async_event_cr = htole16(softc->nq_rings[0].ring.phys_id); 2180 else 2181 req.async_event_cr = htole16(softc->def_cp_ring.ring.phys_id); 2182 2183 rc = hwrm_send_message(softc, &req, sizeof(req)); 2184 2185 return rc; 2186 } 2187 2188 void 2189 bnxt_validate_hw_lro_settings(struct bnxt_softc *softc) 2190 { 2191 softc->hw_lro.enable = min(softc->hw_lro.enable, 1); 2192 2193 softc->hw_lro.is_mode_gro = min(softc->hw_lro.is_mode_gro, 1); 2194 2195 softc->hw_lro.max_agg_segs = min(softc->hw_lro.max_agg_segs, 2196 HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX); 2197 2198 softc->hw_lro.max_aggs = min(softc->hw_lro.max_aggs, 2199 HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX); 2200 2201 softc->hw_lro.min_agg_len = min(softc->hw_lro.min_agg_len, BNXT_MAX_MTU); 2202 } 2203 2204 int 2205 bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc) 2206 { 2207 struct hwrm_vnic_tpa_cfg_input req = {0}; 2208 uint32_t flags; 2209 2210 if (softc->vnic_info.id == (uint16_t) HWRM_NA_SIGNATURE) { 2211 return 0; 2212 } 2213 2214 if (!(softc->flags & BNXT_FLAG_TPA)) 2215 return 0; 2216 2217 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_TPA_CFG); 2218 2219 if (softc->hw_lro.enable) { 2220 flags = HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA | 2221 HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA | 2222 HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN | 2223 HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ; 2224 2225 if (softc->hw_lro.is_mode_gro) 2226 flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO; 2227 else 2228 flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE; 2229 2230 req.flags = htole32(flags); 2231 2232 req.enables = htole32(HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS | 2233 HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS | 2234 HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN); 2235 2236 req.max_agg_segs = htole16(softc->hw_lro.max_agg_segs); 2237 req.max_aggs = htole16(softc->hw_lro.max_aggs); 2238 req.min_agg_len = htole32(softc->hw_lro.min_agg_len); 2239 } 2240 2241 req.vnic_id = htole16(softc->vnic_info.id); 2242 2243 return hwrm_send_message(softc, &req, sizeof(req)); 2244 } 2245 2246 int 2247 bnxt_hwrm_nvm_find_dir_entry(struct bnxt_softc *softc, uint16_t type, 2248 uint16_t *ordinal, uint16_t ext, uint16_t *index, bool use_index, 2249 uint8_t search_opt, uint32_t *data_length, uint32_t *item_length, 2250 uint32_t *fw_ver) 2251 { 2252 struct hwrm_nvm_find_dir_entry_input req = {0}; 2253 struct hwrm_nvm_find_dir_entry_output *resp = 2254 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2255 int rc = 0; 2256 uint32_t old_timeo; 2257 2258 MPASS(ordinal); 2259 2260 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_FIND_DIR_ENTRY); 2261 if (use_index) { 2262 req.enables = htole32( 2263 HWRM_NVM_FIND_DIR_ENTRY_INPUT_ENABLES_DIR_IDX_VALID); 2264 req.dir_idx = htole16(*index); 2265 } 2266 req.dir_type = htole16(type); 2267 req.dir_ordinal = htole16(*ordinal); 2268 req.dir_ext = htole16(ext); 2269 req.opt_ordinal = search_opt; 2270 2271 BNXT_HWRM_LOCK(softc); 2272 old_timeo = softc->hwrm_cmd_timeo; 2273 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2274 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2275 softc->hwrm_cmd_timeo = old_timeo; 2276 if (rc) 2277 goto exit; 2278 2279 if (item_length) 2280 *item_length = le32toh(resp->dir_item_length); 2281 if (data_length) 2282 *data_length = le32toh(resp->dir_data_length); 2283 if (fw_ver) 2284 *fw_ver = le32toh(resp->fw_ver); 2285 *ordinal = le16toh(resp->dir_ordinal); 2286 if (index) 2287 *index = le16toh(resp->dir_idx); 2288 2289 exit: 2290 BNXT_HWRM_UNLOCK(softc); 2291 return (rc); 2292 } 2293 2294 int 2295 bnxt_hwrm_nvm_read(struct bnxt_softc *softc, uint16_t index, uint32_t offset, 2296 uint32_t length, struct iflib_dma_info *data) 2297 { 2298 struct hwrm_nvm_read_input req = {0}; 2299 int rc; 2300 uint32_t old_timeo; 2301 2302 if (length > data->idi_size) { 2303 rc = EINVAL; 2304 goto exit; 2305 } 2306 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_READ); 2307 req.host_dest_addr = htole64(data->idi_paddr); 2308 req.dir_idx = htole16(index); 2309 req.offset = htole32(offset); 2310 req.len = htole32(length); 2311 BNXT_HWRM_LOCK(softc); 2312 old_timeo = softc->hwrm_cmd_timeo; 2313 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2314 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2315 softc->hwrm_cmd_timeo = old_timeo; 2316 BNXT_HWRM_UNLOCK(softc); 2317 if (rc) 2318 goto exit; 2319 bus_dmamap_sync(data->idi_tag, data->idi_map, BUS_DMASYNC_POSTREAD); 2320 2321 goto exit; 2322 2323 exit: 2324 return rc; 2325 } 2326 2327 int 2328 bnxt_hwrm_nvm_modify(struct bnxt_softc *softc, uint16_t index, uint32_t offset, 2329 void *data, bool cpyin, uint32_t length) 2330 { 2331 struct hwrm_nvm_modify_input req = {0}; 2332 struct iflib_dma_info dma_data; 2333 int rc; 2334 uint32_t old_timeo; 2335 2336 if (length == 0 || !data) 2337 return EINVAL; 2338 rc = iflib_dma_alloc(softc->ctx, length, &dma_data, 2339 BUS_DMA_NOWAIT); 2340 if (rc) 2341 return ENOMEM; 2342 if (cpyin) { 2343 rc = copyin(data, dma_data.idi_vaddr, length); 2344 if (rc) 2345 goto exit; 2346 } 2347 else 2348 memcpy(dma_data.idi_vaddr, data, length); 2349 bus_dmamap_sync(dma_data.idi_tag, dma_data.idi_map, 2350 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2351 2352 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_MODIFY); 2353 req.host_src_addr = htole64(dma_data.idi_paddr); 2354 req.dir_idx = htole16(index); 2355 req.offset = htole32(offset); 2356 req.len = htole32(length); 2357 BNXT_HWRM_LOCK(softc); 2358 old_timeo = softc->hwrm_cmd_timeo; 2359 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2360 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2361 softc->hwrm_cmd_timeo = old_timeo; 2362 BNXT_HWRM_UNLOCK(softc); 2363 2364 exit: 2365 iflib_dma_free(&dma_data); 2366 return rc; 2367 } 2368 2369 int 2370 bnxt_hwrm_fw_reset(struct bnxt_softc *softc, uint8_t processor, 2371 uint8_t *selfreset) 2372 { 2373 struct hwrm_fw_reset_input req = {0}; 2374 struct hwrm_fw_reset_output *resp = 2375 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2376 int rc; 2377 2378 MPASS(selfreset); 2379 2380 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_RESET); 2381 req.embedded_proc_type = processor; 2382 req.selfrst_status = *selfreset; 2383 2384 BNXT_HWRM_LOCK(softc); 2385 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2386 if (rc) 2387 goto exit; 2388 *selfreset = resp->selfrst_status; 2389 2390 exit: 2391 BNXT_HWRM_UNLOCK(softc); 2392 return rc; 2393 } 2394 2395 int 2396 bnxt_hwrm_fw_qstatus(struct bnxt_softc *softc, uint8_t type, uint8_t *selfreset) 2397 { 2398 struct hwrm_fw_qstatus_input req = {0}; 2399 struct hwrm_fw_qstatus_output *resp = 2400 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2401 int rc; 2402 2403 MPASS(selfreset); 2404 2405 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_QSTATUS); 2406 req.embedded_proc_type = type; 2407 2408 BNXT_HWRM_LOCK(softc); 2409 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2410 if (rc) 2411 goto exit; 2412 *selfreset = resp->selfrst_status; 2413 2414 exit: 2415 BNXT_HWRM_UNLOCK(softc); 2416 return rc; 2417 } 2418 2419 int 2420 bnxt_hwrm_nvm_write(struct bnxt_softc *softc, void *data, bool cpyin, 2421 uint16_t type, uint16_t ordinal, uint16_t ext, uint16_t attr, 2422 uint16_t option, uint32_t data_length, bool keep, uint32_t *item_length, 2423 uint16_t *index) 2424 { 2425 struct hwrm_nvm_write_input req = {0}; 2426 struct hwrm_nvm_write_output *resp = 2427 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2428 struct iflib_dma_info dma_data; 2429 int rc; 2430 uint32_t old_timeo; 2431 2432 if (data_length) { 2433 rc = iflib_dma_alloc(softc->ctx, data_length, &dma_data, 2434 BUS_DMA_NOWAIT); 2435 if (rc) 2436 return ENOMEM; 2437 if (cpyin) { 2438 rc = copyin(data, dma_data.idi_vaddr, data_length); 2439 if (rc) 2440 goto early_exit; 2441 } 2442 else 2443 memcpy(dma_data.idi_vaddr, data, data_length); 2444 bus_dmamap_sync(dma_data.idi_tag, dma_data.idi_map, 2445 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2446 } 2447 else 2448 dma_data.idi_paddr = 0; 2449 2450 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_WRITE); 2451 2452 req.host_src_addr = htole64(dma_data.idi_paddr); 2453 req.dir_type = htole16(type); 2454 req.dir_ordinal = htole16(ordinal); 2455 req.dir_ext = htole16(ext); 2456 req.dir_attr = htole16(attr); 2457 req.dir_data_length = htole32(data_length); 2458 req.option = htole16(option); 2459 if (keep) { 2460 req.flags = 2461 htole16(HWRM_NVM_WRITE_INPUT_FLAGS_KEEP_ORIG_ACTIVE_IMG); 2462 } 2463 if (item_length) 2464 req.dir_item_length = htole32(*item_length); 2465 2466 BNXT_HWRM_LOCK(softc); 2467 old_timeo = softc->hwrm_cmd_timeo; 2468 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2469 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2470 softc->hwrm_cmd_timeo = old_timeo; 2471 if (rc) 2472 goto exit; 2473 if (item_length) 2474 *item_length = le32toh(resp->dir_item_length); 2475 if (index) 2476 *index = le16toh(resp->dir_idx); 2477 2478 exit: 2479 BNXT_HWRM_UNLOCK(softc); 2480 early_exit: 2481 if (data_length) 2482 iflib_dma_free(&dma_data); 2483 return rc; 2484 } 2485 2486 int 2487 bnxt_hwrm_nvm_erase_dir_entry(struct bnxt_softc *softc, uint16_t index) 2488 { 2489 struct hwrm_nvm_erase_dir_entry_input req = {0}; 2490 uint32_t old_timeo; 2491 int rc; 2492 2493 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_ERASE_DIR_ENTRY); 2494 req.dir_idx = htole16(index); 2495 BNXT_HWRM_LOCK(softc); 2496 old_timeo = softc->hwrm_cmd_timeo; 2497 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2498 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2499 softc->hwrm_cmd_timeo = old_timeo; 2500 BNXT_HWRM_UNLOCK(softc); 2501 return rc; 2502 } 2503 2504 int 2505 bnxt_hwrm_nvm_get_dir_info(struct bnxt_softc *softc, uint32_t *entries, 2506 uint32_t *entry_length) 2507 { 2508 struct hwrm_nvm_get_dir_info_input req = {0}; 2509 struct hwrm_nvm_get_dir_info_output *resp = 2510 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2511 int rc; 2512 uint32_t old_timeo; 2513 2514 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_GET_DIR_INFO); 2515 2516 BNXT_HWRM_LOCK(softc); 2517 old_timeo = softc->hwrm_cmd_timeo; 2518 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2519 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2520 softc->hwrm_cmd_timeo = old_timeo; 2521 if (rc) 2522 goto exit; 2523 2524 if (entries) 2525 *entries = le32toh(resp->entries); 2526 if (entry_length) 2527 *entry_length = le32toh(resp->entry_length); 2528 2529 exit: 2530 BNXT_HWRM_UNLOCK(softc); 2531 return rc; 2532 } 2533 2534 int 2535 bnxt_hwrm_nvm_get_dir_entries(struct bnxt_softc *softc, uint32_t *entries, 2536 uint32_t *entry_length, struct iflib_dma_info *dma_data) 2537 { 2538 struct hwrm_nvm_get_dir_entries_input req = {0}; 2539 uint32_t ent; 2540 uint32_t ent_len; 2541 int rc; 2542 uint32_t old_timeo; 2543 2544 if (!entries) 2545 entries = &ent; 2546 if (!entry_length) 2547 entry_length = &ent_len; 2548 2549 rc = bnxt_hwrm_nvm_get_dir_info(softc, entries, entry_length); 2550 if (rc) 2551 goto exit; 2552 if (*entries * *entry_length > dma_data->idi_size) { 2553 rc = EINVAL; 2554 goto exit; 2555 } 2556 2557 /* 2558 * TODO: There's a race condition here that could blow up DMA memory... 2559 * we need to allocate the max size, not the currently in use 2560 * size. The command should totally have a max size here. 2561 */ 2562 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_GET_DIR_ENTRIES); 2563 req.host_dest_addr = htole64(dma_data->idi_paddr); 2564 BNXT_HWRM_LOCK(softc); 2565 old_timeo = softc->hwrm_cmd_timeo; 2566 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2567 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2568 softc->hwrm_cmd_timeo = old_timeo; 2569 BNXT_HWRM_UNLOCK(softc); 2570 if (rc) 2571 goto exit; 2572 bus_dmamap_sync(dma_data->idi_tag, dma_data->idi_map, 2573 BUS_DMASYNC_POSTWRITE); 2574 2575 exit: 2576 return rc; 2577 } 2578 2579 int 2580 bnxt_hwrm_nvm_get_dev_info(struct bnxt_softc *softc, uint16_t *mfg_id, 2581 uint16_t *device_id, uint32_t *sector_size, uint32_t *nvram_size, 2582 uint32_t *reserved_size, uint32_t *available_size) 2583 { 2584 struct hwrm_nvm_get_dev_info_input req = {0}; 2585 struct hwrm_nvm_get_dev_info_output *resp = 2586 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2587 int rc; 2588 uint32_t old_timeo; 2589 2590 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_GET_DEV_INFO); 2591 2592 BNXT_HWRM_LOCK(softc); 2593 old_timeo = softc->hwrm_cmd_timeo; 2594 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2595 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2596 softc->hwrm_cmd_timeo = old_timeo; 2597 if (rc) 2598 goto exit; 2599 2600 if (mfg_id) 2601 *mfg_id = le16toh(resp->manufacturer_id); 2602 if (device_id) 2603 *device_id = le16toh(resp->device_id); 2604 if (sector_size) 2605 *sector_size = le32toh(resp->sector_size); 2606 if (nvram_size) 2607 *nvram_size = le32toh(resp->nvram_size); 2608 if (reserved_size) 2609 *reserved_size = le32toh(resp->reserved_size); 2610 if (available_size) 2611 *available_size = le32toh(resp->available_size); 2612 2613 exit: 2614 BNXT_HWRM_UNLOCK(softc); 2615 return rc; 2616 } 2617 2618 int 2619 bnxt_hwrm_nvm_install_update(struct bnxt_softc *softc, 2620 uint32_t install_type, uint64_t *installed_items, uint8_t *result, 2621 uint8_t *problem_item, uint8_t *reset_required) 2622 { 2623 struct hwrm_nvm_install_update_input req = {0}; 2624 struct hwrm_nvm_install_update_output *resp = 2625 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2626 int rc; 2627 uint32_t old_timeo; 2628 2629 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_INSTALL_UPDATE); 2630 req.install_type = htole32(install_type); 2631 2632 BNXT_HWRM_LOCK(softc); 2633 old_timeo = softc->hwrm_cmd_timeo; 2634 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2635 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2636 softc->hwrm_cmd_timeo = old_timeo; 2637 if (rc) 2638 goto exit; 2639 2640 if (installed_items) 2641 *installed_items = le32toh(resp->installed_items); 2642 if (result) 2643 *result = resp->result; 2644 if (problem_item) 2645 *problem_item = resp->problem_item; 2646 if (reset_required) 2647 *reset_required = resp->reset_required; 2648 2649 exit: 2650 BNXT_HWRM_UNLOCK(softc); 2651 return rc; 2652 } 2653 2654 int 2655 bnxt_hwrm_nvm_verify_update(struct bnxt_softc *softc, uint16_t type, 2656 uint16_t ordinal, uint16_t ext) 2657 { 2658 struct hwrm_nvm_verify_update_input req = {0}; 2659 uint32_t old_timeo; 2660 int rc; 2661 2662 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_NVM_VERIFY_UPDATE); 2663 2664 req.dir_type = htole16(type); 2665 req.dir_ordinal = htole16(ordinal); 2666 req.dir_ext = htole16(ext); 2667 2668 BNXT_HWRM_LOCK(softc); 2669 old_timeo = softc->hwrm_cmd_timeo; 2670 softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO; 2671 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2672 softc->hwrm_cmd_timeo = old_timeo; 2673 BNXT_HWRM_UNLOCK(softc); 2674 return rc; 2675 } 2676 2677 int 2678 bnxt_hwrm_fw_get_time(struct bnxt_softc *softc, uint16_t *year, uint8_t *month, 2679 uint8_t *day, uint8_t *hour, uint8_t *minute, uint8_t *second, 2680 uint16_t *millisecond, uint16_t *zone) 2681 { 2682 struct hwrm_fw_get_time_input req = {0}; 2683 struct hwrm_fw_get_time_output *resp = 2684 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2685 int rc; 2686 2687 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_GET_TIME); 2688 2689 BNXT_HWRM_LOCK(softc); 2690 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2691 if (rc) 2692 goto exit; 2693 2694 if (year) 2695 *year = le16toh(resp->year); 2696 if (month) 2697 *month = resp->month; 2698 if (day) 2699 *day = resp->day; 2700 if (hour) 2701 *hour = resp->hour; 2702 if (minute) 2703 *minute = resp->minute; 2704 if (second) 2705 *second = resp->second; 2706 if (millisecond) 2707 *millisecond = le16toh(resp->millisecond); 2708 if (zone) 2709 *zone = le16toh(resp->zone); 2710 2711 exit: 2712 BNXT_HWRM_UNLOCK(softc); 2713 return rc; 2714 } 2715 2716 int 2717 bnxt_hwrm_fw_set_time(struct bnxt_softc *softc, uint16_t year, uint8_t month, 2718 uint8_t day, uint8_t hour, uint8_t minute, uint8_t second, 2719 uint16_t millisecond, uint16_t zone) 2720 { 2721 struct hwrm_fw_set_time_input req = {0}; 2722 2723 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_SET_TIME); 2724 2725 req.year = htole16(year); 2726 req.month = month; 2727 req.day = day; 2728 req.hour = hour; 2729 req.minute = minute; 2730 req.second = second; 2731 req.millisecond = htole16(millisecond); 2732 req.zone = htole16(zone); 2733 return hwrm_send_message(softc, &req, sizeof(req)); 2734 } 2735 2736 int bnxt_read_sfp_module_eeprom_info(struct bnxt_softc *softc, uint16_t i2c_addr, 2737 uint16_t page_number, uint8_t bank,bool bank_sel_en, uint16_t start_addr, 2738 uint16_t data_length, uint8_t *buf) 2739 { 2740 struct hwrm_port_phy_i2c_read_output *output = 2741 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2742 struct hwrm_port_phy_i2c_read_input req = {0}; 2743 int rc = 0, byte_offset = 0; 2744 2745 BNXT_HWRM_LOCK(softc); 2746 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_I2C_READ); 2747 2748 req.i2c_slave_addr = i2c_addr; 2749 req.page_number = htole16(page_number); 2750 req.port_id = htole16(softc->pf.port_id); 2751 do { 2752 uint16_t xfer_size; 2753 2754 xfer_size = min_t(uint16_t, data_length, BNXT_MAX_PHY_I2C_RESP_SIZE); 2755 data_length -= xfer_size; 2756 req.page_offset = htole16(start_addr + byte_offset); 2757 req.data_length = xfer_size; 2758 req.bank_number = bank; 2759 req.enables = htole32((start_addr + byte_offset ? 2760 HWRM_PORT_PHY_I2C_READ_INPUT_ENABLES_PAGE_OFFSET : 0) | 2761 (bank_sel_en ? 2762 HWRM_PORT_PHY_I2C_READ_INPUT_ENABLES_BANK_NUMBER : 0)); 2763 rc = hwrm_send_message(softc, &req, sizeof(req)); 2764 if (!rc) 2765 memcpy(buf + byte_offset, output->data, xfer_size); 2766 byte_offset += xfer_size; 2767 } while (!rc && data_length > 0); 2768 2769 BNXT_HWRM_UNLOCK(softc); 2770 2771 return rc; 2772 } 2773 2774 int 2775 bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc) 2776 { 2777 struct bnxt_link_info *link_info = &softc->link_info; 2778 struct hwrm_port_phy_qcfg_input req = {0}; 2779 struct hwrm_port_phy_qcfg_output *resp = 2780 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2781 int rc = 0; 2782 2783 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_QCFG); 2784 2785 BNXT_HWRM_LOCK(softc); 2786 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2787 if (rc) 2788 goto exit; 2789 2790 memcpy(&link_info->phy_qcfg_resp, resp, sizeof(*resp)); 2791 link_info->phy_link_status = resp->link; 2792 link_info->duplex = resp->duplex_cfg; 2793 link_info->auto_mode = resp->auto_mode; 2794 2795 /* 2796 * When AUTO_PAUSE_AUTONEG_PAUSE bit is set to 1, 2797 * the advertisement of pause is enabled. 2798 * 1. When the auto_mode is not set to none and this flag is set to 1, 2799 * then the auto_pause bits on this port are being advertised and 2800 * autoneg pause results are being interpreted. 2801 * 2. When the auto_mode is not set to none and this flag is set to 0, 2802 * the pause is forced as indicated in force_pause, and also 2803 * advertised as auto_pause bits, but the autoneg results are not 2804 * interpreted since the pause configuration is being forced. 2805 * 3. When the auto_mode is set to none and this flag is set to 1, 2806 * auto_pause bits should be ignored and should be set to 0. 2807 */ 2808 2809 link_info->flow_ctrl.autoneg = false; 2810 link_info->flow_ctrl.tx = false; 2811 link_info->flow_ctrl.rx = false; 2812 2813 if ((resp->auto_mode) && 2814 (resp->auto_pause & BNXT_AUTO_PAUSE_AUTONEG_PAUSE)) { 2815 link_info->flow_ctrl.autoneg = true; 2816 } 2817 2818 if (link_info->flow_ctrl.autoneg) { 2819 if (resp->auto_pause & BNXT_PAUSE_TX) 2820 link_info->flow_ctrl.tx = true; 2821 if (resp->auto_pause & BNXT_PAUSE_RX) 2822 link_info->flow_ctrl.rx = true; 2823 } else { 2824 if (resp->force_pause & BNXT_PAUSE_TX) 2825 link_info->flow_ctrl.tx = true; 2826 if (resp->force_pause & BNXT_PAUSE_RX) 2827 link_info->flow_ctrl.rx = true; 2828 } 2829 2830 link_info->duplex_setting = resp->duplex_cfg; 2831 if (link_info->phy_link_status == HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK) 2832 link_info->link_speed = le16toh(resp->link_speed); 2833 else 2834 link_info->link_speed = 0; 2835 link_info->force_link_speed = le16toh(resp->force_link_speed); 2836 link_info->auto_link_speeds = le16toh(resp->auto_link_speed); 2837 link_info->support_speeds = le16toh(resp->support_speeds); 2838 link_info->auto_link_speeds = le16toh(resp->auto_link_speed_mask); 2839 link_info->preemphasis = le32toh(resp->preemphasis); 2840 link_info->phy_ver[0] = resp->phy_maj; 2841 link_info->phy_ver[1] = resp->phy_min; 2842 link_info->phy_ver[2] = resp->phy_bld; 2843 snprintf(softc->ver_info->phy_ver, sizeof(softc->ver_info->phy_ver), 2844 "%d.%d.%d", link_info->phy_ver[0], link_info->phy_ver[1], 2845 link_info->phy_ver[2]); 2846 strlcpy(softc->ver_info->phy_vendor, resp->phy_vendor_name, 2847 BNXT_NAME_SIZE); 2848 strlcpy(softc->ver_info->phy_partnumber, resp->phy_vendor_partnumber, 2849 BNXT_NAME_SIZE); 2850 link_info->media_type = resp->media_type; 2851 link_info->phy_type = resp->phy_type; 2852 link_info->transceiver = resp->xcvr_pkg_type; 2853 link_info->phy_addr = resp->eee_config_phy_addr & 2854 HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_MASK; 2855 link_info->module_status = resp->module_status; 2856 link_info->support_pam4_speeds = le16toh(resp->support_pam4_speeds); 2857 link_info->auto_pam4_link_speeds = le16toh(resp->auto_pam4_link_speed_mask); 2858 link_info->force_pam4_link_speed = le16toh(resp->force_pam4_link_speed); 2859 2860 if (softc->hwrm_spec_code >= 0x10504) 2861 link_info->active_fec_sig_mode = resp->active_fec_signal_mode; 2862 2863 exit: 2864 BNXT_HWRM_UNLOCK(softc); 2865 return rc; 2866 } 2867 2868 static bool 2869 bnxt_phy_qcaps_no_speed(struct hwrm_port_phy_qcaps_output *resp) 2870 { 2871 if (!resp->supported_speeds_auto_mode && 2872 !resp->supported_speeds_force_mode && 2873 !resp->supported_pam4_speeds_auto_mode && 2874 !resp->supported_pam4_speeds_force_mode) 2875 return true; 2876 2877 return false; 2878 } 2879 2880 int bnxt_hwrm_phy_qcaps(struct bnxt_softc *softc) 2881 { 2882 struct bnxt_link_info *link_info = &softc->link_info; 2883 struct hwrm_port_phy_qcaps_output *resp = 2884 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2885 struct hwrm_port_phy_qcaps_input req = {}; 2886 int rc; 2887 2888 if (softc->hwrm_spec_code < 0x10201) 2889 return 0; 2890 2891 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_QCAPS); 2892 2893 BNXT_HWRM_LOCK(softc); 2894 rc = _hwrm_send_message(softc, &req, sizeof(req)); 2895 if (rc) 2896 goto exit; 2897 2898 softc->phy_flags = resp->flags | (resp->flags2 << 8); 2899 if (resp->flags & HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS_EEE_SUPPORTED) { 2900 2901 softc->lpi_tmr_lo = le32toh(resp->tx_lpi_timer_low) & 2902 HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_LOW_MASK; 2903 softc->lpi_tmr_hi = le32toh(resp->valid_tx_lpi_timer_high) & 2904 HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_HIGH_MASK; 2905 } 2906 2907 if (softc->hwrm_spec_code >= 0x10a01) { 2908 if (bnxt_phy_qcaps_no_speed(resp)) { 2909 link_info->phy_state = BNXT_PHY_STATE_DISABLED; 2910 device_printf(softc->dev, "Ethernet link disabled\n"); 2911 } else if (link_info->phy_state == BNXT_PHY_STATE_DISABLED) { 2912 link_info->phy_state = BNXT_PHY_STATE_ENABLED; 2913 device_printf(softc->dev, "Ethernet link enabled\n"); 2914 /* Phy re-enabled, reprobe the speeds */ 2915 link_info->support_auto_speeds = 0; 2916 link_info->support_pam4_auto_speeds = 0; 2917 } 2918 } 2919 if (resp->supported_speeds_auto_mode) 2920 link_info->support_auto_speeds = 2921 le16toh(resp->supported_speeds_auto_mode); 2922 if (resp->supported_speeds_force_mode) 2923 link_info->support_force_speeds = 2924 le16toh(resp->supported_speeds_force_mode); 2925 if (resp->supported_pam4_speeds_auto_mode) 2926 link_info->support_pam4_auto_speeds = 2927 le16toh(resp->supported_pam4_speeds_auto_mode); 2928 if (resp->supported_pam4_speeds_force_mode) 2929 link_info->support_pam4_force_speeds = 2930 le16toh(resp->supported_pam4_speeds_force_mode); 2931 2932 exit: 2933 BNXT_HWRM_UNLOCK(softc); 2934 return rc; 2935 } 2936 2937 uint16_t 2938 bnxt_hwrm_get_wol_fltrs(struct bnxt_softc *softc, uint16_t handle) 2939 { 2940 struct hwrm_wol_filter_qcfg_input req = {0}; 2941 struct hwrm_wol_filter_qcfg_output *resp = 2942 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2943 uint16_t next_handle = 0; 2944 int rc; 2945 2946 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_WOL_FILTER_QCFG); 2947 req.port_id = htole16(softc->pf.port_id); 2948 req.handle = htole16(handle); 2949 rc = hwrm_send_message(softc, &req, sizeof(req)); 2950 if (!rc) { 2951 next_handle = le16toh(resp->next_handle); 2952 if (next_handle != 0) { 2953 if (resp->wol_type == 2954 HWRM_WOL_FILTER_ALLOC_INPUT_WOL_TYPE_MAGICPKT) { 2955 softc->wol = 1; 2956 softc->wol_filter_id = resp->wol_filter_id; 2957 } 2958 } 2959 } 2960 return next_handle; 2961 } 2962 2963 int 2964 bnxt_hwrm_alloc_wol_fltr(struct bnxt_softc *softc) 2965 { 2966 struct hwrm_wol_filter_alloc_input req = {0}; 2967 struct hwrm_wol_filter_alloc_output *resp = 2968 (void *)softc->hwrm_cmd_resp.idi_vaddr; 2969 int rc; 2970 2971 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_WOL_FILTER_ALLOC); 2972 req.port_id = htole16(softc->pf.port_id); 2973 req.wol_type = HWRM_WOL_FILTER_ALLOC_INPUT_WOL_TYPE_MAGICPKT; 2974 req.enables = 2975 htole32(HWRM_WOL_FILTER_ALLOC_INPUT_ENABLES_MAC_ADDRESS); 2976 memcpy(req.mac_address, softc->func.mac_addr, ETHER_ADDR_LEN); 2977 rc = hwrm_send_message(softc, &req, sizeof(req)); 2978 if (!rc) 2979 softc->wol_filter_id = resp->wol_filter_id; 2980 2981 return rc; 2982 } 2983 2984 int 2985 bnxt_hwrm_free_wol_fltr(struct bnxt_softc *softc) 2986 { 2987 struct hwrm_wol_filter_free_input req = {0}; 2988 2989 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_WOL_FILTER_FREE); 2990 req.port_id = htole16(softc->pf.port_id); 2991 req.enables = 2992 htole32(HWRM_WOL_FILTER_FREE_INPUT_ENABLES_WOL_FILTER_ID); 2993 req.wol_filter_id = softc->wol_filter_id; 2994 return hwrm_send_message(softc, &req, sizeof(req)); 2995 } 2996 2997 static void bnxt_hwrm_set_coal_params(struct bnxt_softc *softc, uint32_t max_frames, 2998 uint32_t buf_tmrs, uint16_t flags, 2999 struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req) 3000 { 3001 req->flags = htole16(flags); 3002 req->num_cmpl_dma_aggr = htole16((uint16_t)max_frames); 3003 req->num_cmpl_dma_aggr_during_int = htole16(max_frames >> 16); 3004 req->cmpl_aggr_dma_tmr = htole16((uint16_t)buf_tmrs); 3005 req->cmpl_aggr_dma_tmr_during_int = htole16(buf_tmrs >> 16); 3006 /* Minimum time between 2 interrupts set to buf_tmr x 2 */ 3007 req->int_lat_tmr_min = htole16((uint16_t)buf_tmrs * 2); 3008 req->int_lat_tmr_max = htole16((uint16_t)buf_tmrs * 4); 3009 req->num_cmpl_aggr_int = htole16((uint16_t)max_frames * 4); 3010 } 3011 3012 int bnxt_hwrm_set_coal(struct bnxt_softc *softc) 3013 { 3014 int i, rc = 0; 3015 struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0}, 3016 req_tx = {0}, *req; 3017 uint16_t max_buf, max_buf_irq; 3018 uint16_t buf_tmr, buf_tmr_irq; 3019 uint32_t flags; 3020 3021 bnxt_hwrm_cmd_hdr_init(softc, &req_rx, 3022 HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS); 3023 bnxt_hwrm_cmd_hdr_init(softc, &req_tx, 3024 HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS); 3025 3026 /* Each rx completion (2 records) should be DMAed immediately. 3027 * DMA 1/4 of the completion buffers at a time. 3028 */ 3029 max_buf = min_t(uint16_t, softc->rx_coal_frames / 4, 2); 3030 /* max_buf must not be zero */ 3031 max_buf = clamp_t(uint16_t, max_buf, 1, 63); 3032 max_buf_irq = clamp_t(uint16_t, softc->rx_coal_frames_irq, 1, 63); 3033 buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs); 3034 /* buf timer set to 1/4 of interrupt timer */ 3035 buf_tmr = max_t(uint16_t, buf_tmr / 4, 1); 3036 buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs_irq); 3037 buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1); 3038 3039 flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET; 3040 3041 /* RING_IDLE generates more IRQs for lower latency. Enable it only 3042 * if coal_usecs is less than 25 us. 3043 */ 3044 if (softc->rx_coal_usecs < 25) 3045 flags |= HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE; 3046 3047 bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf, 3048 buf_tmr_irq << 16 | buf_tmr, flags, &req_rx); 3049 3050 /* max_buf must not be zero */ 3051 max_buf = clamp_t(uint16_t, softc->tx_coal_frames, 1, 63); 3052 max_buf_irq = clamp_t(uint16_t, softc->tx_coal_frames_irq, 1, 63); 3053 buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs); 3054 /* buf timer set to 1/4 of interrupt timer */ 3055 buf_tmr = max_t(uint16_t, buf_tmr / 4, 1); 3056 buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs_irq); 3057 buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1); 3058 flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET; 3059 bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf, 3060 buf_tmr_irq << 16 | buf_tmr, flags, &req_tx); 3061 3062 for (i = 0; i < softc->nrxqsets; i++) { 3063 3064 req = &req_rx; 3065 req->ring_id = htole16(softc->grp_info[i].cp_ring_id); 3066 3067 rc = hwrm_send_message(softc, req, sizeof(*req)); 3068 if (rc) 3069 break; 3070 } 3071 return rc; 3072 } 3073 3074 void bnxt_hwrm_ring_info_get(struct bnxt_softc *softc, uint8_t ring_type, 3075 uint32_t ring_id, uint32_t *prod, uint32_t *cons) 3076 { 3077 hwrm_dbg_ring_info_get_input_t req = {0}; 3078 hwrm_dbg_ring_info_get_output_t *resp = (void *)softc->hwrm_cmd_resp.idi_vaddr; 3079 int rc = 0; 3080 3081 *prod = *cons = 0xffffffff; 3082 bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_DBG_RING_INFO_GET); 3083 req.ring_type = le32toh(ring_type); 3084 req.fw_ring_id = le32toh(ring_id); 3085 rc = hwrm_send_message(softc, &req, sizeof(req)); 3086 if (!rc) { 3087 *prod = resp->producer_index; 3088 *cons = resp->consumer_index; 3089 } 3090 3091 return; 3092 } 3093