Author: shurd
Date: Tue Dec 19 21:07:30 2017
New Revision: 327000
URL: https://svnweb.freebsd.org/changeset/base/327000

Log:
  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.marre...@broadcom.com>
  Sponsored by: Broadcom Limited
  Differential Revision:        https://reviews.freebsd.org/D13269?id=36180

Modified:
  head/sys/dev/bnxt/bnxt.h
  head/sys/dev/bnxt/bnxt_hwrm.c
  head/sys/dev/bnxt/bnxt_hwrm.h
  head/sys/dev/bnxt/if_bnxt.c

Modified: head/sys/dev/bnxt/bnxt.h
==============================================================================
--- head/sys/dev/bnxt/bnxt.h    Tue Dec 19 20:32:45 2017        (r326999)
+++ head/sys/dev/bnxt/bnxt.h    Tue Dec 19 21:07:30 2017        (r327000)
@@ -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;

Modified: head/sys/dev/bnxt/bnxt_hwrm.c
==============================================================================
--- head/sys/dev/bnxt/bnxt_hwrm.c       Tue Dec 19 20:32:45 2017        
(r326999)
+++ head/sys/dev/bnxt/bnxt_hwrm.c       Tue Dec 19 21:07:30 2017        
(r327000)
@@ -122,12 +122,37 @@ _hwrm_send_message(struct bnxt_softc *softc, void *msg
        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
        }
 
        /* 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;
@@ -322,6 +348,11 @@ bnxt_hwrm_ver_get(struct bnxt_softc *softc)
                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);

Modified: head/sys/dev/bnxt/bnxt_hwrm.h
==============================================================================
--- head/sys/dev/bnxt/bnxt_hwrm.h       Tue Dec 19 20:32:45 2017        
(r326999)
+++ head/sys/dev/bnxt/bnxt_hwrm.h       Tue Dec 19 21:07:30 2017        
(r327000)
@@ -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);

Modified: head/sys/dev/bnxt/if_bnxt.c
==============================================================================
--- head/sys/dev/bnxt/if_bnxt.c Tue Dec 19 20:32:45 2017        (r326999)
+++ head/sys/dev/bnxt/if_bnxt.c Tue Dec 19 21:07:30 2017        (r327000)
@@ -643,6 +643,23 @@ cp_alloc_fail:
        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 @@ drv_rgtr_fail:
        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);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to