Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Dec 2017 21:07:30 +0000 (UTC)
From:      Stephen Hurd <shurd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r327000 - head/sys/dev/bnxt
Message-ID:  <201712192107.vBJL7VCU022391@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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.marreddy@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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201712192107.vBJL7VCU022391>