git: 2f1d2b99e734 - stable/13 - if_bnxt: Add support for async link status update

From: Warner Losh <imp_at_FreeBSD.org>
Date: Thu, 19 Jan 2023 03:52:14 UTC
The branch stable/13 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=2f1d2b99e73442a143da20d91971f0dd89209881

commit 2f1d2b99e73442a143da20d91971f0dd89209881
Author:     Sumit Saxena <sumit.saxena@broadcom.com>
AuthorDate: 2022-11-04 22:14:49 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-01-19 01:00:06 +0000

    if_bnxt: Add support for async link status update
    
    Reivewed by: imp
    Differential Revision: https://reviews.freebsd.org/D36440
    
    (cherry picked from commit fb4b7e02d236c2c06a87fc3dacd8af6bcfbfb5c1)
---
 sys/dev/bnxt/bnxt.h      |  4 +++
 sys/dev/bnxt/bnxt_hwrm.c | 27 +++++++----------
 sys/dev/bnxt/if_bnxt.c   | 75 +++++++++++++++++++++++++++++++++++++-----------
 3 files changed, 73 insertions(+), 33 deletions(-)

diff --git a/sys/dev/bnxt/bnxt.h b/sys/dev/bnxt/bnxt.h
index 61c0a0f8bd36..753d1aac92de 100644
--- a/sys/dev/bnxt/bnxt.h
+++ b/sys/dev/bnxt/bnxt.h
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/socket.h>
 #include <sys/sysctl.h>
 #include <sys/taskqueue.h>
+#include <sys/bitstring.h>
 
 #include <machine/bus.h>
 
@@ -666,6 +667,9 @@ struct bnxt_softc {
 #define BNXT_FLAG_CHIP_P5 	0x0020
 #define BNXT_FLAG_TPA	 	0x0040
 	uint32_t		flags;
+#define BNXT_STATE_LINK_CHANGE  (0)
+#define BNXT_STATE_MAX		(BNXT_STATE_LINK_CHANGE + 1)
+	bitstr_t 		*state_bv;
 	uint32_t		total_msix;
 
 	struct bnxt_func_info	func;
diff --git a/sys/dev/bnxt/bnxt_hwrm.c b/sys/dev/bnxt/bnxt_hwrm.c
index 761b08f6925d..eb1c60ac35d6 100644
--- a/sys/dev/bnxt/bnxt_hwrm.c
+++ b/sys/dev/bnxt/bnxt_hwrm.c
@@ -30,7 +30,6 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/endian.h>
-#include <sys/bitstring.h>
 
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
@@ -1511,28 +1510,22 @@ int
 bnxt_cfg_async_cr(struct bnxt_softc *softc)
 {
 	int rc = 0;
+	struct hwrm_func_cfg_input req = {0};
 
-	if (BNXT_PF(softc)) {
-		struct hwrm_func_cfg_input req = {0};
+	if (!BNXT_PF(softc))
+		return 0;
 
-		bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG);
+	bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG);
 
-		req.fid = htole16(0xffff);
-		req.enables = htole32(HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+	req.fid = htole16(0xffff);
+	req.enables = htole32(HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+	if (BNXT_CHIP_P5(softc))
+		req.async_event_cr = htole16(softc->nq_rings[0].ring.phys_id);
+	else
 		req.async_event_cr = htole16(softc->def_cp_ring.ring.phys_id);
 
-		rc = hwrm_send_message(softc, &req, sizeof(req));
-	}
-	else {
-		struct hwrm_func_vf_cfg_input req = {0};
-
-		bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_VF_CFG);
-
-		req.enables = htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
-		req.async_event_cr = htole16(softc->def_cp_ring.ring.phys_id);
+	rc = hwrm_send_message(softc, &req, sizeof(req));
 
-		rc = hwrm_send_message(softc, &req, sizeof(req));
-	}
 	return rc;
 }
 
diff --git a/sys/dev/bnxt/if_bnxt.c b/sys/dev/bnxt/if_bnxt.c
index 06b5bbfb907e..6b4e7b516b67 100644
--- a/sys/dev/bnxt/if_bnxt.c
+++ b/sys/dev/bnxt/if_bnxt.c
@@ -1514,6 +1514,8 @@ bnxt_attach_pre(if_ctx_t ctx)
 	/* Initialize the vlan list */
 	SLIST_INIT(&softc->vnic_info.vlan_tags);
 	softc->vnic_info.vlan_tag_list.idi_vaddr = NULL;
+	softc->state_bv = bit_alloc(BNXT_STATE_MAX, M_DEVBUF,
+			M_WAITOK|M_ZERO);
 
 	return (rc);
 
@@ -1609,6 +1611,7 @@ bnxt_detach(if_ctx_t ctx)
 	bnxt_free_hwrm_short_cmd_req(softc);
 	BNXT_HWRM_LOCK_DESTROY(softc);
 
+	free(softc->state_bv, M_DEVBUF);
 	pci_disable_busmaster(softc->dev);
 	bnxt_pci_mapping_free(softc);
 
@@ -1746,11 +1749,6 @@ bnxt_init(if_ctx_t ctx)
 	if (rc)
 		goto fail;
 skip_def_cp_ring:
-	/* And now set the default CP ring as the async CP ring */
-	rc = bnxt_cfg_async_cr(softc);
-	if (rc)
-		goto fail;
-
 	for (i = 0; i < softc->nrxqsets; i++) {
 		/* Allocate the statistics context */
 		rc = bnxt_hwrm_stat_ctx_alloc(softc, &softc->rx_cp_rings[i],
@@ -1813,6 +1811,11 @@ skip_def_cp_ring:
 			goto fail;
 	}
 
+	/* And now set the default CP / NQ ring for the async */
+	rc = bnxt_cfg_async_cr(softc);
+	if (rc)
+		goto fail;
+
 	/* Allocate the VNIC RSS context */
 	rc = bnxt_hwrm_vnic_ctx_alloc(softc, &softc->vnic_info.rss_id);
 	if (rc)
@@ -2138,10 +2141,20 @@ bnxt_update_admin_status(if_ctx_t ctx)
 
 	/*
 	 * When SR-IOV is enabled, avoid each VF sending this HWRM
-         * request every sec with which firmware timeouts can happen
-         */
-	if (BNXT_PF(softc)) {
-		bnxt_hwrm_port_qstats(softc);
+	 * request every sec with which firmware timeouts can happen
+	 */
+	if (!BNXT_PF(softc))
+		return;
+
+	bnxt_hwrm_port_qstats(softc);
+
+	if (BNXT_CHIP_P5(softc)) {
+		struct ifmediareq ifmr;
+
+		if (bit_test(softc->state_bv, BNXT_STATE_LINK_CHANGE)) {
+			bit_clear(softc->state_bv, BNXT_STATE_LINK_CHANGE);
+			bnxt_media_status(softc->ctx, &ifmr);
+		}
 	}
 
 	return;
@@ -2155,7 +2168,7 @@ bnxt_if_timer(if_ctx_t ctx, uint16_t qid)
 	uint64_t ticks_now = ticks;
 
         /* Schedule bnxt_update_admin_status() once per sec */
-        if (ticks_now - softc->admin_ticks >= hz) {
+	if (ticks_now - softc->admin_ticks >= hz) {
 		softc->admin_ticks = ticks_now;
 		iflib_admin_intr_deferred(ctx);
 	}
@@ -2222,6 +2235,34 @@ bnxt_tx_queue_intr_enable(if_ctx_t ctx, uint16_t qid)
 	return 0;
 }
 
+static void
+bnxt_process_cmd_cmpl(struct bnxt_softc *softc, hwrm_cmpl_t *cmd_cmpl)
+{
+	device_printf(softc->dev, "cmd sequence number %d\n",
+			cmd_cmpl->sequence_id);
+	return;
+}
+
+static void
+bnxt_process_async_msg(struct bnxt_cp_ring *cpr, tx_cmpl_t *cmpl)
+{
+	struct bnxt_softc *softc = cpr->ring.softc;
+	uint16_t type = cmpl->flags_type & TX_CMPL_TYPE_MASK;
+
+	switch (type) {
+	case HWRM_CMPL_TYPE_HWRM_DONE:
+		bnxt_process_cmd_cmpl(softc, (hwrm_cmpl_t *)cmpl);
+		break;
+	case HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT:
+		bnxt_handle_async_event(softc, (cmpl_base_t *) cmpl);
+		break;
+	default:
+		device_printf(softc->dev, "%s:%d Unhandled async message %x\n",
+				__FUNCTION__, __LINE__, type);
+		break;
+	}
+}
+
 static void
 process_nq(struct bnxt_softc *softc, uint16_t nqid)
 {
@@ -2235,14 +2276,13 @@ process_nq(struct bnxt_softc *softc, uint16_t nqid)
 		if (!NQ_VALID(&cmp[cons], v_bit))
 			goto done;
 
-		NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
-		nqe_cnt++;
-
 		nq_type = NQ_CN_TYPE_MASK & cmp[cons].type;
 
-		/* TBD - Handle Async events */
 		if (nq_type != NQ_CN_TYPE_CQ_NOTIFICATION)
-			device_printf(softc->dev, "%s: %d nq_type  0x%x\n", __FUNCTION__, __LINE__, nq_type);
+			 bnxt_process_async_msg(cpr, (tx_cmpl_t *)&cmp[cons]);
+
+		NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
+		nqe_cnt++;
 	}
 done:
 	if (nqe_cnt) {
@@ -3110,7 +3150,10 @@ bnxt_handle_async_event(struct bnxt_softc *softc, struct cmpl_base *cmpl)
 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
-		bnxt_media_status(softc->ctx, &ifmr);
+		if (BNXT_CHIP_P5(softc))
+			bit_set(softc->state_bv, BNXT_STATE_LINK_CHANGE);
+		else
+			bnxt_media_status(softc->ctx, &ifmr);
 		break;
 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE:
 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE: