Support short HWRM commands

New Stratus bnxt devices require support for short HWRM commands for VFs
to function.  Enable their use, but only use them if it's both supported
and required... prefer the long HWRM commands when possible.

Submitted by:	Bhargava Chenna Marreddy <bhargava.marreddy@broadcom.com>
Sponsored by:	Broadcom Limited
Differential Revision:	https://reviews.freebsd.org/D13269?id=36180
This commit is contained in:
Stephen Hurd 2017-12-19 21:07:30 +00:00
parent 6a0dc418a6
commit 980da9f2f0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=327000
4 changed files with 61 additions and 1 deletions

View File

@ -561,6 +561,7 @@ struct bnxt_softc {
#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 @@ struct bnxt_softc {
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;

View File

@ -122,12 +122,37 @@ _hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
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 @@ _hwrm_send_message(struct bnxt_softc *softc, void *msg, uint32_t msg_len)
}
/* 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 @@ bnxt_hwrm_ver_get(struct bnxt_softc *softc)
int rc;
const char nastr[] = "<not installed>";
const char naver[] = "<N/A>";
uint32_t dev_caps_cfg;
softc->hwrm_max_req_len = HWRM_MAX_REQ_LEN;
softc->hwrm_cmd_timeo = 1000;
@ -323,6 +349,11 @@ bnxt_hwrm_ver_get(struct bnxt_softc *softc)
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);
return rc;

View File

@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#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);

View File

@ -643,6 +643,23 @@ bnxt_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs,
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 @@ bnxt_attach_pre(if_ctx_t ctx)
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 @@ bnxt_attach_pre(if_ctx_t ctx)
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_detach(if_ctx_t ctx)
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);