From nobody Fri Oct 09 10:13:02 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4j1N3L66NBz6vRmR for ; Fri, 09 Oct 2026 10:13:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4j1N3L38Qzz4YVS for ; Fri, 09 Oct 2026 10:13:02 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791540782; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Y8znMSZR3fSBbgrE1UKJCuBGPhlMd6M9QP0403eRUlE=; b=mZdQ0bxFak0/GiPlJOgUsjTrp+RhFbPayeDfW7GjkXy6S9Gu8evleP+B0V5HdZxQ80qTsK NYHKQ0g7d7/EHyn4jqRdFs8uMhBpiO2qeta4tPHQg/Ik4be4aTKNRpRicnHNGCBNqC7JnH BjfxrDQtekShkd74ZrKfTeaN+H9DC/Xf7U/NhopSCzQLxr+Me1culDiCoy5aT6KmDAgNfZ fFjR0AtZqq/5syLfSCJ6twDGgpv7T030t/keKkw20Opl1CVKJiU+UwlrAMS89doIV7VRIZ uAi0dR8Tlp7ezPUJ39co1i0AfYAa/VsGS7tt5fxqRSMDh/SFcrVNNNHe8iFgOA== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791540782; b=SyhRWU7Tr6yJ4JOn+vphH/dpwHC6PjznMLP7AEtidD/9SV0RSw8qsPoYGBvXNJI4obiQND 2unTDk2QDeh1k1JCPZ5HfyQ6k7AJQB+MH1wK4S78T/VVzwADk//aBGlujCHCZOLZ1Ek5Kk kt4PqHlMK5VykuneXhV+5VTon3UATWz5JLkCvqS2I22wdEyIOUoPXxZO4htmTTg+7WbWxQ 8vYeN553oIpAzZUUVECMTR16OyMKYugYaXSwB0i5+DgDYZtV5sPeHHVyVUB/eH5jpoyaXI ML3ckNDe3qng5Xve4NvbBdEIbngsb+9E7/+sPt1Ly0wyum7QCz1wUz3/0B4kgA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791540782; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Y8znMSZR3fSBbgrE1UKJCuBGPhlMd6M9QP0403eRUlE=; b=kKJ2NGG8egDu8BbFUI1HRt3bWW8+WE8rhBH9ZdsTjS0PtUgc7PoRQ5zfLz6hil4t82UwA0 MzGO5k8D5foNordu+IUNHmz4XQSz8yxFN0+WEHduBEImVUncUi0R0rShhw9GFDD1BBRAuZ IsNjmz5CUJwTDf5Oo/Kte60DP5BpNJKNPy2GBzsNfHbBcajHij7BPGfD2aCfVAZmqsaomD vcZ+maLv1QG21+ZZaCvs9tChpv4VU4IUOnbFl2RvABADmxh65E/Ke2yZeHuEhlDO5x7sX1 YdHNbO6oDsSWWoO/lUTITFIX4bstgrgBaASUTN1gMI/RS7IkkiRESQIn/GABRQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4j1N3L1jS3z1L1T for ; Fri, 09 Oct 2026 10:13:02 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 43a90 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 09 Oct 2026 10:13:02 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Sumit Saxena From: Sumit Saxena Subject: git: 22dcbd7739a1 - main - if_bnxt: port workqueue, task-queue, and synchronization kPIs to FreeBSD natives List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: ssaxena X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 22dcbd7739a174433845da800ad47fa182f37430 Auto-Submitted: auto-generated Date: Fri, 09 Oct 2026 10:13:02 +0000 Message-Id: <6ac8be2e.43a90.4c4f38d6@gitrepo.freebsd.org> The branch main has been updated by ssaxena: URL: https://cgit.FreeBSD.org/src/commit/?id=22dcbd7739a174433845da800ad47fa182f37430 commit 22dcbd7739a174433845da800ad47fa182f37430 Author: Sumit Saxena AuthorDate: 2026-08-05 04:12:53 +0000 Commit: Sumit Saxena CommitDate: 2026-10-09 08:24:46 +0000 if_bnxt: port workqueue, task-queue, and synchronization kPIs to FreeBSD natives - Replace Linux workqueue (struct workqueue_struct, bnxt_pf_wq) with a FreeBSD taskqueue (bnxt_taskq) shared by every attached PF. bnxt_taskq is created once at module load and destroyed once at module unload (SYSINIT/SYSUNINIT on SI_SUB_KLD), matching the module-owned-taskqueue idiom used elsewhere in the tree (e.g. sys/dev/cxgbe/t4_main.c's reset_tq). This replaces an earlier lazy, per-attach/detach create-or-reuse scheme guarded by a mutex and a "ready" flag, which had a real race: bnxt_queue_sp_work()/bnxt_queue_fw_reset_work() and bnxt_attach_pre() re-read the bnxt_taskq/bnxt_taskq_ready globals outside the mutex right after the lazy-init call returned, so a concurrent bnxt_detach() on another PF freeing the shared queue once bnxt_num_pfs hit 0 could race a still-attached PF into enqueuing onto a freed taskqueue. Tying the taskqueue's lifetime to the module instead of to any one PF's attach/detach removes that race outright, since the module can't unload while a PF is still attached. - Replace struct work_struct sp_task with struct task sp_task; replace struct delayed_work fw_reset_task with struct timeout_task fw_reset_tmo. - Replace INIT_WORK/INIT_DELAYED_WORK with TASK_INIT/TIMEOUT_TASK_INIT; queue_work/schedule_work with taskqueue_enqueue; queue_delayed_work/schedule_delayed_work with taskqueue_enqueue_timeout; cancel_work_sync/cancel_delayed_work_sync with taskqueue_drain/taskqueue_drain_timeout. - Rename bnxt_fw_reset_task(struct work_struct *) to bnxt_fw_reset_timeout_task(void *ctx, int pending) to match FreeBSD timeout_task callback signature. - Add inline helpers in bnxt.h to wrap all Linux test_bit/set_bit/ clear_bit/test_and_clear_bit calls on softc->state and softc->sp_event: bnxt_drv_state_test/set/clear/test_and_clear, bnxt_sp_event_set/test_and_clear (implemented via bit_test() from and atomic_testandset_long()/ atomic_testandclear_long(), all bit-index based like the Linux bitops they replace). - Replace struct mutex lock in bnxt_fw_health with struct mtx; mutex_init to mtx_init. - Replace kzalloc/kfree with malloc/free (M_DEVBUF). - Replace DIV_ROUND_UP with howmany; hweight32 with bitcount32. - Replace jiffies/HZ with ticks/hz; msleep with pause_sbt(). Since `ticks` (unlike LinuxKPI's `unsigned long jiffies`) is a 32-bit `volatile int` that wraps every ~24 days at hz=1000, BNXT_TIME_AFTER and bnxt_sleep_until_min_elapsed() compute the ticks delta as `int` (matching the in-tree wraparound-safe idiom used elsewhere, e.g. sys/dev/axgbe/xgbe-mdio.c) rather than widening it to `long`/ `unsigned long`, so the comparison stays correct across a wrap. - Replace IS_ERR_OR_NULL/ERR_PTR with plain NULL checks. Reviewed by: gallatin MFC after: 2 weeks Sponsored by: Broadcom Inc. Differential Revision: https://reviews.freebsd.org/D59089 --- sys/dev/bnxt/bnxt_en/bnxt.h | 48 ++++- sys/dev/bnxt/bnxt_en/bnxt_auxbus_compat.c | 4 +- sys/dev/bnxt/bnxt_en/bnxt_compat.h | 2 +- sys/dev/bnxt/bnxt_en/bnxt_hwrm.c | 2 +- sys/dev/bnxt/bnxt_en/bnxt_ktls.c | 12 +- sys/dev/bnxt/bnxt_en/bnxt_ptp.c | 2 +- sys/dev/bnxt/bnxt_en/bnxt_ulp.c | 5 +- sys/dev/bnxt/bnxt_en/if_bnxt.c | 295 ++++++++++++++++++------------ 8 files changed, 230 insertions(+), 140 deletions(-) diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h index 6509a89fcaec..7c5b357ec7ac 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt.h +++ b/sys/dev/bnxt/bnxt_en/bnxt.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -1150,7 +1151,7 @@ struct bnxt_fw_health { u32 echo_req_data1; u32 echo_req_data2; struct devlink_health_reporter *fw_reporter; - struct mutex lock; + struct mtx lock; enum bnxt_health_severity severity; enum bnxt_health_remedy remedy; u32 arrests; @@ -1526,10 +1527,10 @@ struct bnxt_softc { #define BNXT_STATE_HALF_OPEN 15 #define BNXT_STATE_UP 16 #define BNXT_NO_FW_ACCESS(bp) \ - test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) + bnxt_drv_state_test((bp), BNXT_STATE_FW_FATAL_COND) struct pci_dev *pdev; - struct work_struct sp_task; + struct task sp_task; unsigned long sp_event; #define BNXT_RX_MASK_SP_EVENT 0 #define BNXT_RX_NTP_FLTR_SP_EVENT 1 @@ -1557,7 +1558,7 @@ struct bnxt_softc { #define BNXT_FW_ECHO_REQUEST_SP_EVENT 23 #define BNXT_VF_CFG_CHNG_SP_EVENT 24 - struct delayed_work fw_reset_task; + struct timeout_task fw_reset_tmo; int fw_reset_state; #define BNXT_FW_RESET_STATE_POLL_VF 1 #define BNXT_FW_RESET_STATE_RESET_FW 2 @@ -1623,6 +1624,45 @@ struct bnxt_softc { uint8_t tx_hw_coal_cnt; }; +/* softc->state helpers */ +static __inline bool +bnxt_drv_state_test(const struct bnxt_softc *sc, unsigned int bit) +{ + /* Paired with the atomic RMWs the write-side helpers below use. */ + return (atomic_load_acq_long(&sc->state) & (1UL << bit)) != 0; +} + +static __inline void +bnxt_drv_state_set(struct bnxt_softc *sc, unsigned int bit) +{ + atomic_testandset_long(&sc->state, bit); +} + +static __inline void +bnxt_drv_state_clear(struct bnxt_softc *sc, unsigned int bit) +{ + atomic_testandclear_long(&sc->state, bit); +} + +static __inline bool +bnxt_drv_state_test_and_clear(struct bnxt_softc *sc, unsigned int bit) +{ + return atomic_testandclear_long(&sc->state, bit); +} + +/* softc->sp_event helpers */ +static __inline void +bnxt_sp_event_set(struct bnxt_softc *sc, unsigned int bit) +{ + atomic_testandset_long(&sc->sp_event, bit); +} + +static __inline bool +bnxt_sp_event_test_and_clear(struct bnxt_softc *sc, unsigned int bit) +{ + return atomic_testandclear_long(&sc->sp_event, bit); +} + struct bnxt_filter_info { STAILQ_ENTRY(bnxt_filter_info) next; uint64_t fw_l2_filter_id; diff --git a/sys/dev/bnxt/bnxt_en/bnxt_auxbus_compat.c b/sys/dev/bnxt/bnxt_en/bnxt_auxbus_compat.c index 1014d360015a..de7f46f6a900 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_auxbus_compat.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_auxbus_compat.c @@ -31,8 +31,8 @@ #include #include #include -#include +#include "bnxt_compat.h" #include "bnxt_auxbus_compat.h" static struct list_head bnxt_aux_bus_dev_list = LINUX_LIST_HEAD_INIT(bnxt_aux_bus_dev_list); @@ -92,7 +92,7 @@ int auxiliary_device_add(struct auxiliary_device *auxdev) mutex_lock(&bnxt_auxbus_lock); list_for_each_entry(auxdrv, &bnxt_aux_bus_drv_list, list) { if (auxdrv) { - msleep(2 * 1000); + pause_sbt("bxtms", SBT_1MS * 2 * 1000, 0, C_HARDCLOCK); id = auxiliary_match_id(auxdrv->id_table, auxdev); if (id) { diff --git a/sys/dev/bnxt/bnxt_en/bnxt_compat.h b/sys/dev/bnxt/bnxt_en/bnxt_compat.h index 0a1c47b6cd92..3ca02fb84ee4 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_compat.h +++ b/sys/dev/bnxt/bnxt_en/bnxt_compat.h @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -46,7 +47,6 @@ __FBSDID("$FreeBSD$"); #include #include - #if (__FreeBSD_version < 1500000) #define if_getmtu(ifp) (ifp)->if_mtu diff --git a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c index 77e43079fd96..f31b19878e55 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c @@ -3630,7 +3630,7 @@ int bnxt_hwrm_set_coal(struct bnxt_softc *softc) struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req = {0}; int i, rc = 0; - if (!test_bit(BNXT_STATE_UP, &softc->state)) + if (!bnxt_drv_state_test(softc, BNXT_STATE_UP)) return (rc); bnxt_hwrm_cmd_hdr_init(softc, &req, diff --git a/sys/dev/bnxt/bnxt_en/bnxt_ktls.c b/sys/dev/bnxt/bnxt_en/bnxt_ktls.c index 31549707d275..01f1c711ca0e 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_ktls.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_ktls.c @@ -177,7 +177,7 @@ int bnxt_tls_snd_tag_alloc(if_t ifp, union if_snd_tag_alloc_params* params, priv = iflib_get_softc(ctx); ktls = priv->ktls_info; - if (!test_bit(BNXT_STATE_OPEN, &priv->state)) + if (!bnxt_drv_state_test(priv, BNXT_STATE_OPEN)) return (EPROTONOSUPPORT); if (atomic_load_acq_int(&priv->detached)) @@ -999,8 +999,8 @@ static int bnxt_crypto_del(struct bnxt_softc* softc, uint32_t data; uint32_t kid; - if (test_bit(BNXT_STATE_IN_FW_RESET, &softc->state) && - test_bit(BNXT_STATE_FW_FATAL_COND, &softc->state)) + if (bnxt_drv_state_test(softc, BNXT_STATE_IN_FW_RESET) && + bnxt_drv_state_test(softc, BNXT_STATE_FW_FATAL_COND)) return 0; kid = kctx_tx->kid; @@ -1026,7 +1026,7 @@ static int bnxt_ktls_dev_add(struct bnxt_softc* softc, atomic_add_32(&ktls->pending, 1); atomic_thread_fence_seq_cst(); - if (!test_bit(BNXT_STATE_OPEN, &softc->state)) { + if (!bnxt_drv_state_test(softc, BNXT_STATE_OPEN)) { BNXT_DEBUG(softc->dev, "kTLS dev_add: device not open\n"); rc = ENODEV; goto exit; @@ -1082,7 +1082,7 @@ static void bnxt_ktls_dev_del(struct bnxt_softc* softc, * BNXT_STATE_OPEN is cleared (and MPC rings freed) in bnxt_stop(); * bail out here to avoid MPC command timeouts while unloading. */ - if (!test_bit(BNXT_STATE_OPEN, &softc->state)) { + if (!bnxt_drv_state_test(softc, BNXT_STATE_OPEN)) { BNXT_DEBUG(softc->dev, "[KID:%u]: KTLS dev_del: device not up, freeing KID\n", kid); bnxt_free_one_kctx(kctx, kid, softc->dev); counter_u64_add(ktls->counters[BNXT_KTLS_TX_DEL], 1); @@ -1095,7 +1095,7 @@ retry: * BNXT_STATE_OPEN flag. */ atomic_thread_fence_seq_cst(); - while (!test_bit(BNXT_STATE_OPEN, &softc->state)) { + while (!bnxt_drv_state_test(softc, BNXT_STATE_OPEN)) { atomic_subtract_32(&ktls->pending, 1); if (retry_cnt > BNXT_RETRY_MAX) { device_printf(softc->dev, diff --git a/sys/dev/bnxt/bnxt_en/bnxt_ptp.c b/sys/dev/bnxt/bnxt_en/bnxt_ptp.c index 73d0c24c63f1..ff3fac22538b 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_ptp.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_ptp.c @@ -90,7 +90,7 @@ __bnxt_refclk_read(struct bnxt_softc *bp, uint64_t *ns) struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; uint32_t high_before, high_now, low; - if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) + if (bnxt_drv_state_test(bp, BNXT_STATE_IN_FW_RESET)) return (EIO); /* Refclk registers live in the HWRM BAR, not the doorbell BAR. */ diff --git a/sys/dev/bnxt/bnxt_en/bnxt_ulp.c b/sys/dev/bnxt/bnxt_en/bnxt_ulp.c index cd6df3b17d63..00a9f5ba2a70 100644 --- a/sys/dev/bnxt/bnxt_en/bnxt_ulp.c +++ b/sys/dev/bnxt/bnxt_en/bnxt_ulp.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -76,7 +75,7 @@ static int bnxt_register_dev(struct bnxt_en_dev *edev, int ulp_id, rcu_assign_pointer(ulp->ulp_ops, ulp_ops); if (ulp_id == BNXT_ROCE_ULP) { - if (test_bit(BNXT_STATE_OPEN, &bp->state) && bp->is_dev_init) + if (bnxt_drv_state_test(bp, BNXT_STATE_OPEN) && bp->is_dev_init) bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info); } @@ -111,7 +110,7 @@ static int bnxt_unregister_dev(struct bnxt_en_dev *edev, int ulp_id) ulp->async_events_bmap = NULL; mtx_unlock(&bp->en_ops_lock); while (atomic_read(&ulp->ref_count) != 0 && i < 10) { - msleep(100); + pause_sbt("bxtms", SBT_1MS * 100, 0, C_HARDCLOCK); i++; } /* Tell the caller a ULP consumer may still hold a reference into torn-down state. */ diff --git a/sys/dev/bnxt/bnxt_en/if_bnxt.c b/sys/dev/bnxt/bnxt_en/if_bnxt.c index c30c608875be..0c4ae738b557 100644 --- a/sys/dev/bnxt/bnxt_en/if_bnxt.c +++ b/sys/dev/bnxt/bnxt_en/if_bnxt.c @@ -35,6 +35,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -51,12 +56,11 @@ #define WANT_NATIVE_PCI_GET_SLOT #include +#include #include #include -#include #include #include -#include #include #include "opt_inet.h" #include "opt_inet6.h" @@ -80,6 +84,8 @@ #include "bnxt_mpc.h" #include "bnxt_ktls.h" +#define BNXT_TIME_AFTER(a, b) (((int)((a) - (b)) > 0)) + /* * PCI Device ID Table */ @@ -508,7 +514,33 @@ bnxt_set_flags_by_devid(struct bnxt_softc *softc) } #define PCI_SUBSYSTEM_ID 0x2e -static struct workqueue_struct *bnxt_pf_wq; +static struct taskqueue *bnxt_taskq; + +/* Taskqueue shared by every attached PF; created at module load, destroyed at unload. */ +static void +bnxt_taskq_create(void *arg __unused) +{ + + bnxt_taskq = taskqueue_create("bnxt", M_WAITOK, + taskqueue_thread_enqueue, &bnxt_taskq); + if (taskqueue_start_threads(&bnxt_taskq, 1, PWAIT, "bnxt taskq") != 0) { + log(LOG_ERR, "bnxt: unable to start taskqueue thread\n"); + taskqueue_free(bnxt_taskq); + bnxt_taskq = NULL; + } +} +SYSINIT(bnxt_taskq_create, SI_SUB_TASKQ, SI_ORDER_ANY, bnxt_taskq_create, NULL); + +static void +bnxt_taskq_destroy(void *arg __unused) +{ + + if (bnxt_taskq != NULL) + taskqueue_free(bnxt_taskq); +} +SYSUNINIT(bnxt_taskq_destroy, SI_SUB_TASKQ, SI_ORDER_ANY, bnxt_taskq_destroy, NULL); + +static void bnxt_fw_reset_timeout_task(void *ctx, int pending); extern void bnxt_destroy_irq(struct bnxt_softc *softc); @@ -1153,7 +1185,7 @@ bnxt_alloc_ctx_pg_tbls(struct bnxt_softc *softc, if (!mem_size) return -EINVAL; - ctx_pg->nr_pages = DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE); + ctx_pg->nr_pages = howmany(mem_size, BNXT_PAGE_SIZE); if (ctx_pg->nr_pages > MAX_CTX_TOTAL_PAGES) { ctx_pg->nr_pages = 0; return -EINVAL; @@ -1162,11 +1194,11 @@ bnxt_alloc_ctx_pg_tbls(struct bnxt_softc *softc, int nr_tbls, i; rmem->depth = 2; - ctx_pg->ctx_pg_tbl = kzalloc(MAX_CTX_PAGES * sizeof(ctx_pg), - GFP_KERNEL); + ctx_pg->ctx_pg_tbl = malloc(MAX_CTX_PAGES * sizeof(ctx_pg), + M_DEVBUF, M_WAITOK | M_ZERO); if (!ctx_pg->ctx_pg_tbl) return -ENOMEM; - nr_tbls = DIV_ROUND_UP(ctx_pg->nr_pages, MAX_CTX_PAGES); + nr_tbls = howmany(ctx_pg->nr_pages, MAX_CTX_PAGES); rmem->nr_pages = nr_tbls; rc = bnxt_alloc_ctx_mem_blk(softc, ctx_pg); if (rc) @@ -1174,7 +1206,7 @@ bnxt_alloc_ctx_pg_tbls(struct bnxt_softc *softc, for (i = 0; i < nr_tbls; i++) { struct bnxt_ctx_pg_info *pg_tbl; - pg_tbl = kzalloc(sizeof(*pg_tbl), GFP_KERNEL); + pg_tbl = malloc(sizeof(*pg_tbl), M_DEVBUF, M_WAITOK | M_ZERO); if (!pg_tbl) return -ENOMEM; ctx_pg->ctx_pg_tbl[i] = pg_tbl; @@ -1194,7 +1226,7 @@ bnxt_alloc_ctx_pg_tbls(struct bnxt_softc *softc, break; } } else { - rmem->nr_pages = DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE); + rmem->nr_pages = howmany(mem_size, BNXT_PAGE_SIZE); if (rmem->nr_pages > 1 || depth) rmem->depth = 1; rmem->ctx_mem = ctxm; @@ -1225,7 +1257,7 @@ void bnxt_free_ctx_pg_tbls(struct bnxt_softc *softc, free(pg_tbl , M_DEVBUF); ctx_pg->ctx_pg_tbl[i] = NULL; } - kfree(ctx_pg->ctx_pg_tbl); + free(ctx_pg->ctx_pg_tbl, M_DEVBUF); ctx_pg->ctx_pg_tbl = NULL; } bnxt_free_ring(softc, rmem); @@ -1243,7 +1275,7 @@ static int bnxt_setup_ctxm_pg_tbls(struct bnxt_softc *softc, if (!ctxm->entry_size || !ctx_pg) return -EINVAL; if (ctxm->instance_bmap) - n = hweight32(ctxm->instance_bmap); + n = bitcount32(ctxm->instance_bmap); if (ctxm->entry_multiple) entries = roundup(entries, ctxm->entry_multiple); entries = clamp_t(u32, entries, ctxm->min_entries, ctxm->max_entries); @@ -1274,16 +1306,16 @@ static void bnxt_free_ctx_mem(struct bnxt_softc *softc) if (!ctx_pg) continue; if (ctxm->instance_bmap) - n = hweight32(ctxm->instance_bmap); + n = bitcount32(ctxm->instance_bmap); for (i = 0; i < n; i++) bnxt_free_ctx_pg_tbls(softc, &ctx_pg[i]); - kfree(ctx_pg); + free(ctx_pg, M_DEVBUF); ctxm->pg_info = NULL; } ctx->flags &= ~BNXT_CTX_FLAG_INITED; - kfree(ctx); + free(ctx, M_DEVBUF); softc->ctx_mem = NULL; } @@ -1316,7 +1348,7 @@ bnxt_bs_trace_init(struct bnxt_softc *bp, struct bnxt_ctx_mem_type *ctxm) mem_size = ctxm->max_entries * ctxm->entry_size; rem_bytes = mem_size % BNXT_PAGE_SIZE; - pages = DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE); + pages = howmany(mem_size, BNXT_PAGE_SIZE); last_pg = (pages - 1) & (MAX_CTX_PAGES - 1); magic_byte_offset = ((rem_bytes ? rem_bytes : BNXT_PAGE_SIZE) - size); @@ -1902,13 +1934,13 @@ static void bnxt_rtnl_lock_sp(struct bnxt_softc *bp) * rtnl() and waiting for BNXT_STATE_IN_SP_TASK to clear. So we * must clear BNXT_STATE_IN_SP_TASK before holding rtnl(). */ - clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + bnxt_drv_state_clear(bp, BNXT_STATE_IN_SP_TASK); rtnl_lock(); } static void bnxt_rtnl_unlock_sp(struct bnxt_softc *bp) { - set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + bnxt_drv_state_set(bp, BNXT_STATE_IN_SP_TASK); rtnl_unlock(); } @@ -1947,18 +1979,19 @@ static u32 bnxt_fw_health_readl(struct bnxt_softc *bp, int reg_idx) } /* - * Sleep until at least min_ms milliseconds have passed since start_jiffies. + * Sleep until at least min_ms milliseconds have passed since start_ticks. */ -static void bnxt_sleep_until_min_elapsed(unsigned long start_jiffies, +static void bnxt_sleep_until_min_elapsed(unsigned long start_ticks, unsigned int min_ms) { - unsigned long elapsed_time; + int elapsed_time; unsigned int elapsed_time_ms; - elapsed_time = jiffies - start_jiffies; - elapsed_time_ms = (unsigned int)(elapsed_time * 1000 / HZ); + elapsed_time = (int)(ticks - start_ticks); + elapsed_time_ms = (unsigned int)(elapsed_time * 1000 / hz); if (elapsed_time_ms < min_ms) - msleep(min_ms - elapsed_time_ms); + pause_sbt("bxtms", SBT_1MS * (min_ms - elapsed_time_ms), 0, + C_HARDCLOCK); } static void bnxt_fw_reset_close(struct bnxt_softc *bp) @@ -1969,7 +2002,7 @@ static void bnxt_fw_reset_close(struct bnxt_softc *bp) * bus master to prevent any potential bad DMAs before freeing * kernel memory. */ - if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state)) { + if (bnxt_drv_state_test(bp, BNXT_STATE_FW_FATAL_COND)) { u16 val = 0; val = pci_read_config(bp->dev, PCI_SUBSYSTEM_ID, 2); @@ -2015,18 +2048,18 @@ static bool is_bnxt_fw_ok(struct bnxt_softc *bp) void bnxt_fw_reset(struct bnxt_softc *bp) { bnxt_rtnl_lock_sp(bp); - if (test_bit(BNXT_STATE_OPEN, &bp->state) && - !test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { + if (bnxt_drv_state_test(bp, BNXT_STATE_OPEN) && + !bnxt_drv_state_test(bp, BNXT_STATE_IN_FW_RESET)) { int tmo; - set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); + bnxt_drv_state_set(bp, BNXT_STATE_IN_FW_RESET); bnxt_fw_reset_close(bp); if ((bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD)) { bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN; - tmo = HZ / 10; + tmo = hz / 10; } else { bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV; - tmo = bp->fw_reset_min_dsecs * HZ /10; + tmo = bp->fw_reset_min_dsecs * hz /10; } bnxt_queue_fw_reset_work(bp, tmo); } @@ -2035,21 +2068,27 @@ void bnxt_fw_reset(struct bnxt_softc *bp) static void bnxt_queue_fw_reset_work(struct bnxt_softc *bp, unsigned long delay) { - if (!(test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))) + int lticks; + + if (!(bnxt_drv_state_test(bp, BNXT_STATE_IN_FW_RESET))) return; - if (BNXT_PF(bp)) - queue_delayed_work(bnxt_pf_wq, &bp->fw_reset_task, delay); - else - schedule_delayed_work(&bp->fw_reset_task, delay); + lticks = (int)delay; + if ((unsigned long)lticks != delay) + lticks = INT_MAX; + if (lticks < 1) + lticks = 1; + if (bnxt_taskq == NULL) + return; + taskqueue_enqueue_timeout(bnxt_taskq, &bp->fw_reset_tmo, lticks); } void bnxt_queue_sp_work(struct bnxt_softc *bp) { - if (BNXT_PF(bp)) - queue_work(bnxt_pf_wq, &bp->sp_task); - else - schedule_work(&bp->sp_task); + + if (bnxt_taskq == NULL) + return; + taskqueue_enqueue(bnxt_taskq, &bp->sp_task); } static void bnxt_fw_reset_writel(struct bnxt_softc *bp, int reg_idx) @@ -2080,7 +2119,7 @@ static void bnxt_fw_reset_writel(struct bnxt_softc *bp, int reg_idx) } if (delay_msecs) { pci_read_config_dword(bp->pdev, 0, &val); - msleep(delay_msecs); + pause_sbt("bxtms", SBT_1MS * delay_msecs, 0, C_HARDCLOCK); } } @@ -2090,7 +2129,7 @@ static void bnxt_reset_all(struct bnxt_softc *bp) int i, rc; if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { - bp->fw_reset_timestamp = jiffies; + bp->fw_reset_timestamp = ticks; return; } @@ -2110,7 +2149,7 @@ static void bnxt_reset_all(struct bnxt_softc *bp) if (rc != -ENODEV) device_printf(bp->dev, "Unable to reset FW rc=%d\n", rc); } - bp->fw_reset_timestamp = jiffies; + bp->fw_reset_timestamp = ticks; } static int __bnxt_alloc_fw_health(struct bnxt_softc *bp) @@ -2118,14 +2157,24 @@ static int __bnxt_alloc_fw_health(struct bnxt_softc *bp) if (bp->fw_health) return 0; - bp->fw_health = kzalloc(sizeof(*bp->fw_health), GFP_KERNEL); + bp->fw_health = malloc(sizeof(*bp->fw_health), M_DEVBUF, M_WAITOK | M_ZERO); if (!bp->fw_health) return -ENOMEM; - mutex_init(&bp->fw_health->lock); + mtx_init(&bp->fw_health->lock, "bnxt_fw_health", NULL, MTX_DEF); return 0; } +static void bnxt_free_fw_health(struct bnxt_softc *bp) +{ + if (!bp->fw_health) + return; + + mtx_destroy(&bp->fw_health->lock); + free(bp->fw_health, M_DEVBUF); + bp->fw_health = NULL; +} + static int bnxt_alloc_fw_health(struct bnxt_softc *bp) { int rc; @@ -2301,8 +2350,8 @@ static int bnxt_drv_rgtr(struct bnxt_softc *bp) static bool bnxt_fw_reset_timeout(struct bnxt_softc *bp) { - return time_after(jiffies, bp->fw_reset_timestamp + - (bp->fw_reset_max_dsecs * HZ / 10)); + return BNXT_TIME_AFTER(ticks, bp->fw_reset_timestamp + + (bp->fw_reset_max_dsecs * hz / 10)); } /* enqueue an iflib reset and wait for RUNNING/OACTIVE to flip 1->0->1. */ @@ -2418,8 +2467,8 @@ static int bnxt_open(struct bnxt_softc *bp) bnxt_msix_intr_assign(bp->ctx, 0); - if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) { - if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { + if (bnxt_drv_state_test_and_clear(bp, BNXT_STATE_FW_RESET_DET)) { + if (!bnxt_drv_state_test(bp, BNXT_STATE_IN_FW_RESET)) { bnxt_ulp_start(bp, 0); } } @@ -2436,20 +2485,24 @@ static int bnxt_open(struct bnxt_softc *bp) } static void bnxt_fw_reset_abort(struct bnxt_softc *bp, int rc) { - clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); + bnxt_drv_state_clear(bp, BNXT_STATE_IN_FW_RESET); if (bp->fw_reset_state != BNXT_FW_RESET_STATE_POLL_VF) { bnxt_ulp_start(bp, rc); } bp->fw_reset_state = 0; } -static void bnxt_fw_reset_task(struct work_struct *work) +static void +bnxt_fw_reset_timeout_task(void *ctx, int pending) { - struct bnxt_softc *bp = container_of(work, struct bnxt_softc, fw_reset_task.work); + struct bnxt_softc *bp = ctx; int rc = 0; - if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { - device_printf(bp->dev, "bnxt_fw_reset_task() called when not in fw reset mode!\n"); + (void)pending; + + if (!bnxt_drv_state_test(bp, BNXT_STATE_IN_FW_RESET)) { + device_printf(bp->dev, + "bnxt_fw_reset_timeout_task() called when not in fw reset mode!\n"); return; } @@ -2460,7 +2513,7 @@ static void bnxt_fw_reset_task(struct work_struct *work) val = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG); if (!(val & BNXT_FW_STATUS_SHUTDOWN) && !bnxt_fw_reset_timeout(bp)) { - bnxt_queue_fw_reset_work(bp, HZ / 5); + bnxt_queue_fw_reset_work(bp, hz / 5); return; } @@ -2468,7 +2521,7 @@ static void bnxt_fw_reset_task(struct work_struct *work) u32 wait_dsecs = bp->fw_health->normal_func_wait_dsecs; bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV; - bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10); + bnxt_queue_fw_reset_work(bp, wait_dsecs * hz / 10); return; } bp->fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW; @@ -2477,11 +2530,11 @@ static void bnxt_fw_reset_task(struct work_struct *work) case BNXT_FW_RESET_STATE_RESET_FW: bnxt_reset_all(bp); bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV; - bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10); + bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * hz / 10); return; case BNXT_FW_RESET_STATE_ENABLE_DEV: bnxt_inv_fw_health_reg(bp); - if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) && + if (bnxt_drv_state_test(bp, BNXT_STATE_FW_FATAL_COND) && !bp->fw_reset_min_dsecs) { u16 val; @@ -2492,12 +2545,12 @@ static void bnxt_fw_reset_task(struct work_struct *work) rc = -ETIMEDOUT; goto fw_reset_abort; } - bnxt_queue_fw_reset_work(bp, HZ / 1000); + bnxt_queue_fw_reset_work(bp, hz / 1000); return; } } - clear_bit(BNXT_STATE_FW_FATAL_COND, &bp->state); - clear_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state); + bnxt_drv_state_clear(bp, BNXT_STATE_FW_FATAL_COND); + bnxt_drv_state_clear(bp, BNXT_STATE_FW_NON_FATAL_COND); if (!pci_is_enabled(bp->pdev)) { if (pci_enable_device(bp->pdev)) { device_printf(bp->dev, "Cannot re-enable PCI device\n"); @@ -2518,7 +2571,7 @@ static void bnxt_fw_reset_task(struct work_struct *work) device_printf(bp->dev, "Firmware reset aborted\n"); goto fw_reset_abort_status; } - bnxt_queue_fw_reset_work(bp, HZ / 5); + bnxt_queue_fw_reset_work(bp, hz / 5); return; } bp->hwrm_cmd_timeo = DFLT_HWRM_CMD_TIMEOUT; @@ -2539,10 +2592,10 @@ static void bnxt_fw_reset_task(struct work_struct *work) } bp->fw_reset_state = 0; smp_mb__before_atomic(); - clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); + bnxt_drv_state_clear(bp, BNXT_STATE_IN_FW_RESET); bnxt_ulp_start(bp, 0); - clear_bit(BNXT_STATE_FW_ACTIVATE, &bp->state); - set_bit(BNXT_STATE_OPEN, &bp->state); + bnxt_drv_state_clear(bp, BNXT_STATE_FW_ACTIVATE); + bnxt_drv_state_set(bp, BNXT_STATE_OPEN); bnxt_crash_dump_init(bp); #ifdef PCI_IOV bnxt_reenable_sriov(bp); @@ -2569,8 +2622,8 @@ static void bnxt_force_fw_reset(struct bnxt_softc *bp) struct bnxt_fw_health *fw_health = bp->fw_health; u32 wait_dsecs; - if (!test_bit(BNXT_STATE_OPEN, &bp->state) || - test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) + if (!bnxt_drv_state_test(bp, BNXT_STATE_OPEN) || + bnxt_drv_state_test(bp, BNXT_STATE_IN_FW_RESET)) return; bnxt_fw_reset_close(bp); wait_dsecs = fw_health->master_func_wait_dsecs; @@ -2579,20 +2632,20 @@ static void bnxt_force_fw_reset(struct bnxt_softc *bp) wait_dsecs = 0; bp->fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW; } else { - bp->fw_reset_timestamp = jiffies + wait_dsecs * HZ / 10; + bp->fw_reset_timestamp = ticks + wait_dsecs * hz / 10; wait_dsecs = fw_health->normal_func_wait_dsecs; bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV; } bp->fw_reset_min_dsecs = fw_health->post_reset_wait_dsecs; bp->fw_reset_max_dsecs = fw_health->post_reset_max_wait_dsecs; - bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10); + bnxt_queue_fw_reset_work(bp, wait_dsecs * hz / 10); } static void bnxt_fw_exception(struct bnxt_softc *bp) { device_printf(bp->dev, "Detected firmware fatal condition, initiating reset\n"); - set_bit(BNXT_STATE_FW_FATAL_COND, &bp->state); + bnxt_drv_state_set(bp, BNXT_STATE_FW_FATAL_COND); bnxt_rtnl_lock_sp(bp); bnxt_force_fw_reset(bp); bnxt_rtnl_unlock_sp(bp); @@ -2600,8 +2653,8 @@ static void bnxt_fw_exception(struct bnxt_softc *bp) static void __bnxt_fw_recover(struct bnxt_softc *bp) { - if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) || - test_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state)) + if (bnxt_drv_state_test(bp, BNXT_STATE_FW_FATAL_COND) || + bnxt_drv_state_test(bp, BNXT_STATE_FW_NON_FATAL_COND)) bnxt_fw_reset(bp); else bnxt_fw_exception(bp); @@ -2620,36 +2673,39 @@ static void bnxt_devlink_health_fw_report(struct bnxt_softc *bp) } } -static void bnxt_sp_task(struct work_struct *work) +static void +bnxt_sp_task(void *ctx, int pending) { - struct bnxt_softc *bp = container_of(work, struct bnxt_softc, sp_task); + struct bnxt_softc *bp = ctx; - set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + (void)pending; + + bnxt_drv_state_set(bp, BNXT_STATE_IN_SP_TASK); smp_mb__after_atomic(); - if (!test_bit(BNXT_STATE_OPEN, &bp->state)) { - clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + if (!bnxt_drv_state_test(bp, BNXT_STATE_OPEN)) { + bnxt_drv_state_clear(bp, BNXT_STATE_IN_SP_TASK); return; } #ifdef PCI_IOV - if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event)) + if (bnxt_sp_event_test_and_clear(bp, BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT)) bnxt_hwrm_exec_fwd_req(bp); #endif - if (test_and_clear_bit(BNXT_FW_RESET_NOTIFY_SP_EVENT, &bp->sp_event)) { - if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) || - test_bit(BNXT_STATE_FW_NON_FATAL_COND, &bp->state)) + if (bnxt_sp_event_test_and_clear(bp, BNXT_FW_RESET_NOTIFY_SP_EVENT)) { + if (bnxt_drv_state_test(bp, BNXT_STATE_FW_FATAL_COND) || + bnxt_drv_state_test(bp, BNXT_STATE_FW_NON_FATAL_COND)) bnxt_devlink_health_fw_report(bp); else bnxt_fw_reset(bp); } - if (test_and_clear_bit(BNXT_FW_EXCEPTION_SP_EVENT, &bp->sp_event)) { + if (bnxt_sp_event_test_and_clear(bp, BNXT_FW_EXCEPTION_SP_EVENT)) { if (!is_bnxt_fw_ok(bp)) bnxt_devlink_health_fw_report(bp); } smp_mb__before_atomic(); - clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + bnxt_drv_state_clear(bp, BNXT_STATE_IN_SP_TASK); } int @@ -2730,7 +2786,7 @@ bnxt_attach_pre(if_ctx_t ctx) goto pci_map_fail; } - softc->pdev = kzalloc(sizeof(*softc->pdev), GFP_KERNEL); + softc->pdev = malloc(sizeof(*softc->pdev), M_DEVBUF, M_WAITOK | M_ZERO); if (!softc->pdev) { device_printf(softc->dev, "pdev alloc failed\n"); rc = -ENOMEM; @@ -2807,16 +2863,6 @@ bnxt_attach_pre(if_ctx_t ctx) /* Get NVRAM info */ if (BNXT_PF(softc)) { - if (!bnxt_pf_wq) { - bnxt_pf_wq = - create_singlethread_workqueue("bnxt_pf_wq"); - if (!bnxt_pf_wq) { - device_printf(softc->dev, "Unable to create workqueue.\n"); - rc = -ENOMEM; - goto nvm_alloc_fail; - } - } - softc->nvm_info = malloc(sizeof(struct bnxt_nvram_info), M_DEVBUF, M_NOWAIT | M_ZERO); if (softc->nvm_info == NULL) { @@ -3137,9 +3183,16 @@ bnxt_attach_pre(if_ctx_t ctx) } } - set_bit(BNXT_STATE_OPEN, &softc->state); - INIT_WORK(&softc->sp_task, bnxt_sp_task); - INIT_DELAYED_WORK(&softc->fw_reset_task, bnxt_fw_reset_task); + bnxt_drv_state_set(softc, BNXT_STATE_OPEN); + if (bnxt_taskq == NULL) { + device_printf(softc->dev, "Unable to create taskqueue.\n"); + rc = -ENOMEM; + bnxt_drv_state_clear(softc, BNXT_STATE_OPEN); + goto failed; + } + TASK_INIT(&softc->sp_task, 0, bnxt_sp_task, softc); + TIMEOUT_TASK_INIT(bnxt_taskq, &softc->fw_reset_tmo, 0, + bnxt_fw_reset_timeout_task, softc); /* Initialize the vlan list */ SLIST_INIT(&softc->vnic_info.vlan_tags); @@ -3178,7 +3231,7 @@ dma_fail: if (softc->pdev) linux_pci_detach_device(softc->pdev); pci_attach_fail: - kfree(softc->pdev); + free(softc->pdev, M_DEVBUF); softc->pdev = NULL; free_pci_map: bnxt_pci_mapping_free(softc); @@ -3294,8 +3347,10 @@ bnxt_detach(if_ctx_t ctx) bnxt_mpc_irq_cleanup(softc); bnxt_rdma_aux_device_uninit(softc); - cancel_delayed_work_sync(&softc->fw_reset_task); - cancel_work_sync(&softc->sp_task); + if (bnxt_taskq != NULL) { + taskqueue_drain_timeout(bnxt_taskq, &softc->fw_reset_tmo); + taskqueue_drain(bnxt_taskq, &softc->sp_task); + } bnxt_dcb_free(softc); #ifdef KERN_TLS @@ -3357,6 +3412,7 @@ bnxt_detach(if_ctx_t ctx) bnxt_free_mpcs(softc); bnxt_free_mpc_info(softc); bnxt_free_ctx_mem(softc); + bnxt_free_fw_health(softc); bnxt_clear_ids(softc); iflib_irq_free(ctx, &softc->def_cp_ring.irq); /* We need to free() these here... */ @@ -3389,11 +3445,6 @@ bnxt_detach(if_ctx_t ctx) bnxt_unregister_logger(softc, BNXT_LOGGER_L2); mtx_destroy(&softc->log_lock); - if (!bnxt_num_pfs && bnxt_pf_wq) { - destroy_workqueue(bnxt_pf_wq); - bnxt_pf_wq = NULL; - } - if (softc->pdev) linux_pci_detach_device(softc->pdev); free(softc->state_bv, M_DEVBUF); @@ -3510,7 +3561,7 @@ bnxt_func_reset(struct bnxt_softc *softc) return; } - if (!test_bit(BNXT_STATE_IN_FW_RESET, &softc->state)) + if (!bnxt_drv_state_test(softc, BNXT_STATE_IN_FW_RESET)) bnxt_hwrm_resource_free(softc); return; } @@ -3562,7 +3613,7 @@ static void bnxt_get_port_module_status(struct bnxt_softc *softc) static void bnxt_aux_dev_free(struct bnxt_softc *softc) { - kfree(softc->aux_dev); + free(softc->aux_dev, M_DEVBUF); softc->aux_dev = NULL; } @@ -3570,12 +3621,12 @@ static struct bnxt_aux_dev *bnxt_aux_dev_init(struct bnxt_softc *softc) { struct bnxt_aux_dev *bnxt_adev; - msleep(1000 * 2); - bnxt_adev = kzalloc(sizeof(*bnxt_adev), GFP_KERNEL); + pause_sbt("bxtms", SBT_1MS * 1000 * 2, 0, C_HARDCLOCK); + bnxt_adev = malloc(sizeof(*bnxt_adev), M_DEVBUF, M_WAITOK | M_ZERO); if (!bnxt_adev) - return ERR_PTR(-ENOMEM); *** 107 LINES SKIPPED ***