Index: head/sys/dev/bnxt/bnxt.h =================================================================== --- head/sys/dev/bnxt/bnxt.h +++ head/sys/dev/bnxt/bnxt.h @@ -561,6 +561,7 @@ #define BNXT_FLAG_VF 0x0001 #define BNXT_FLAG_NPAR 0x0002 #define BNXT_FLAG_WOL_CAP 0x0004 +#define BNXT_FLAG_SHORT_CMD 0x0008 uint32_t flags; uint32_t total_msix; @@ -572,6 +573,7 @@ uint16_t hwrm_cmd_seq; uint32_t hwrm_cmd_timeo; /* milliseconds */ struct iflib_dma_info hwrm_cmd_resp; + struct iflib_dma_info hwrm_short_cmd_req_addr; /* Interrupt info for HWRM */ struct if_irq irq; struct mtx hwrm_lock; Index: head/sys/dev/bnxt/bnxt_hwrm.h =================================================================== --- head/sys/dev/bnxt/bnxt_hwrm.h +++ head/sys/dev/bnxt/bnxt_hwrm.h @@ -36,6 +36,7 @@ #define BNXT_PAUSE_RX (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX) #define BNXT_AUTO_PAUSE_AUTONEG_PAUSE \ (HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE) +#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) /* HWRM Function Prototypes */ int bnxt_alloc_hwrm_dma_mem(struct bnxt_softc *softc); Index: head/sys/dev/bnxt/bnxt_hwrm.c =================================================================== --- head/sys/dev/bnxt/bnxt_hwrm.c +++ head/sys/dev/bnxt/bnxt_hwrm.c @@ -122,12 +122,37 @@ uint16_t cp_ring_id; uint8_t *valid; uint16_t err; + uint16_t max_req_len = HWRM_MAX_REQ_LEN; + struct hwrm_short_input short_input = {0}; /* TODO: DMASYNC in here. */ req->seq_id = htole16(softc->hwrm_cmd_seq++); memset(resp, 0, PAGE_SIZE); cp_ring_id = le16toh(req->cmpl_ring); + if (softc->flags & BNXT_FLAG_SHORT_CMD) { + void *short_cmd_req = softc->hwrm_short_cmd_req_addr.idi_vaddr; + + memcpy(short_cmd_req, req, msg_len); + memset((uint8_t *) short_cmd_req + msg_len, 0, softc->hwrm_max_req_len- + msg_len); + + short_input.req_type = req->req_type; + short_input.signature = + htole16(HWRM_SHORT_INPUT_SIGNATURE_SHORT_CMD); + short_input.size = htole16(msg_len); + short_input.req_addr = + htole64(softc->hwrm_short_cmd_req_addr.idi_paddr); + + data = (uint32_t *)&short_input; + msg_len = sizeof(short_input); + + /* Sync memory write before updating doorbell */ + wmb(); + + max_req_len = BNXT_HWRM_SHORT_REQ_LEN; + } + /* Write request msg to hwrm channel */ for (i = 0; i < msg_len; i += 4) { bus_space_write_4(softc->hwrm_bar.tag, @@ -137,7 +162,7 @@ } /* Clear to the end of the request buffer */ - for (i = msg_len; i < HWRM_MAX_REQ_LEN; i += 4) + for (i = msg_len; i < max_req_len; i += 4) bus_space_write_4(softc->hwrm_bar.tag, softc->hwrm_bar.handle, i, 0); @@ -248,6 +273,7 @@ int rc; const char nastr[] = ""; const char naver[] = ""; + uint32_t dev_caps_cfg; softc->hwrm_max_req_len = HWRM_MAX_REQ_LEN; softc->hwrm_cmd_timeo = 1000; @@ -322,6 +348,11 @@ softc->hwrm_max_req_len = le16toh(resp->max_req_win_len); if (resp->def_req_timeout) softc->hwrm_cmd_timeo = le16toh(resp->def_req_timeout); + + dev_caps_cfg = le32toh(resp->dev_caps_cfg); + if ((dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) && + (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED)) + softc->flags |= BNXT_FLAG_SHORT_CMD; fail: BNXT_HWRM_UNLOCK(softc); Index: head/sys/dev/bnxt/if_bnxt.c =================================================================== --- head/sys/dev/bnxt/if_bnxt.c +++ head/sys/dev/bnxt/if_bnxt.c @@ -643,6 +643,23 @@ return rc; } +static void bnxt_free_hwrm_short_cmd_req(struct bnxt_softc *softc) +{ + if (softc->hwrm_short_cmd_req_addr.idi_vaddr) + iflib_dma_free(&softc->hwrm_short_cmd_req_addr); + softc->hwrm_short_cmd_req_addr.idi_vaddr = NULL; +} + +static int bnxt_alloc_hwrm_short_cmd_req(struct bnxt_softc *softc) +{ + int rc; + + rc = iflib_dma_alloc(softc->ctx, softc->hwrm_max_req_len, + &softc->hwrm_short_cmd_req_addr, BUS_DMA_NOWAIT); + + return rc; +} + /* Device setup and teardown */ static int bnxt_attach_pre(if_ctx_t ctx) @@ -714,6 +731,12 @@ goto ver_fail; } + if (softc->flags & BNXT_FLAG_SHORT_CMD) { + rc = bnxt_alloc_hwrm_short_cmd_req(softc); + if (rc) + goto hwrm_short_cmd_alloc_fail; + } + /* Get NVRAM info */ if (BNXT_PF(softc)) { softc->nvm_info = malloc(sizeof(struct bnxt_nvram_info), @@ -902,6 +925,8 @@ if (BNXT_PF(softc)) free(softc->nvm_info, M_DEVBUF); nvm_alloc_fail: + bnxt_free_hwrm_short_cmd_req(softc); +hwrm_short_cmd_alloc_fail: ver_fail: free(softc->ver_info, M_DEVBUF); ver_alloc_fail: @@ -974,6 +999,7 @@ bnxt_hwrm_func_drv_unrgtr(softc, false); bnxt_free_hwrm_dma_mem(softc); + bnxt_free_hwrm_short_cmd_req(softc); BNXT_HWRM_LOCK_DESTROY(softc); pci_disable_busmaster(softc->dev);