From nobody Sun Nov 01 18:35:35 2026 X-Original-To: dev-commits-src-branches@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 4jHk6b6sQWz6xjJm for ; Sun, 01 Nov 2026 18:35:35 +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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jHk6b3l6gz3KVW for ; Sun, 01 Nov 2026 18:35:35 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793558135; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=OS/wkjTgeu7IinJXbw60coViJDvAjkCrXwSgi2K4QLw=; b=rgg/JIkfzkusfsKwO0dYH57xv8zfhjrcBKJoa4VHWjb4GsPV46Xq3DgXXYFV7ZHsEUjtQi 8S2yhrLFSgLwYRjr7uI+Bg0BaazxZ+h7i/ne3BrbJsHG60Vaxp0289b0FF9odwBFeKikeR AQzxxdx7W1sO3sNDfxP4jxnPRmCzAriGaOXbQ1Cqp4TLP69i7SOF3bWw7arRd3NUeKrAVQ HrTA+Bz2oKxoN2C5S1bhBcRmLc9O2EpA8EtxmfMIKvd5IN9HrIZzi1BgF2ZnBrDNLvIy7Q 1SobFohEr2TmMzAX90m5/7oi7Xl/MHZDp1Y3yQBC+06Sy3wYBH9Iq2vmzxXzOQ== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793558135; b=qYaIf2pkAvJRHqGLNSE2ZWfVv0NRaxO3vNxw9DguWRU6ZOvsnpJFI3QbUfpRwpvlKpx8S5 XYLhWu9xJMTMruc0rHk8T9R/a6niqMhlXwi0jvNQLBOEemeMneIt0O8lXWxNOFtcx5/Ivx GZDbC025C1N+Io2IGtyiwtYcflUIE03pctrRLuspp31sKarVDZ8rxHZPpua/K0XChBJTqf knYUaybZeCkWDLAeg0OaeKi4ZouvZkh8eSQIdrqjtt+3pXRb8BPIhpXdrHRr0OdqCDZZl1 T9gG3oaLsBiv5Hz2qRjWcdE9nuJYaJpiJynKUkgKDQL8mNC+RcHRv4hCqamDpQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793558135; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=OS/wkjTgeu7IinJXbw60coViJDvAjkCrXwSgi2K4QLw=; b=GnQO4gI9CpDSqIcz0ITzOBpH4gOy3EBoVtACMdTxYQZePhD4PeGSua8LeV/f9ac5w/CfNZ slyWcMluzhNEjgvGO/v8mLBM+CBD8GfboewKGu3STCvSELTLW8ltMpUJvyTPBs1F8DMUGd FStGHBc38BDlxls8qlBTiZ2W92CPskJ9KCkCIHPpktvpN7OZkQ6zoWc5pYMbDCAMaeK8/C vWREOTDkGh7iC/V9z/DiZX+mjpddlzg8aIoBmiOOLZrXXuyg/jfgwp8bWcG0cgcN/ACPHZ 5NzffdLwZB5tXtW2BO7SrY7weIGyzf9hzrncqfGuYbOET/ZWCuzGmzbR/VV2pw== 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 4jHk6b350zz19G7 for ; Sun, 01 Nov 2026 18:35:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 20fe5 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 01 Nov 2026 18:35:35 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Abdelkader Boudih Subject: git: 2e2f55cfd9fe - stable/15 - mtw: Fix firmware loading and memory leaks List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: Commits to the stable branches of the FreeBSD src repository 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: seuros X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 2e2f55cfd9fee487a706ed624ad180196f154430 Auto-Submitted: auto-generated Date: Sun, 01 Nov 2026 18:35:35 +0000 Message-Id: <6ae78677.20fe5.19fb239a@gitrepo.freebsd.org> The branch stable/15 has been updated by seuros: URL: https://cgit.FreeBSD.org/src/commit/?id=2e2f55cfd9fee487a706ed624ad180196f154430 commit 2e2f55cfd9fee487a706ed624ad180196f154430 Author: Abdelkader Boudih AuthorDate: 2026-06-17 14:30:21 +0000 Commit: Abdelkader Boudih CommitDate: 2026-11-01 16:59:39 +0000 mtw: Fix firmware loading and memory leaks - Skip firmware reload if MCU already initialized - Fix firmware_put() memory leaks on error paths - Increase MCU init timeout to 15 seconds - Use debug macros instead of device_printf for verbose output - Remove unused 'ret' variable - Fix space indentation to tabs per style(9) Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D57597 (cherry picked from commit f981fa12b760a5f0983eeec8065a4dec5295ab24) --- sys/dev/usb/wlan/if_mtw.c | 103 +++++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/sys/dev/usb/wlan/if_mtw.c b/sys/dev/usb/wlan/if_mtw.c index b6d22eb65c7b..7285939f301e 100644 --- a/sys/dev/usb/wlan/if_mtw.c +++ b/sys/dev/usb/wlan/if_mtw.c @@ -125,6 +125,11 @@ enum { #define MTW_MAX_TXSZ \ (sizeof(struct mtw_txd) + sizeof(struct mtw_txwi) + MCLBYTES + 11) +#define MTW_FW_READY_RETRIES 500 +#define MTW_FW_READY_DELAY_MS 30 +#define MTW_FWLOAD_TIMEOUT \ + (((MTW_FW_READY_RETRIES * MTW_FW_READY_DELAY_MS) / 1000 + 5) * hz) + /* * Because of LOR in mtw_key_delete(), use atomic instead. * '& MTW_CMDQ_MASQ' is to loop cmdq[]. @@ -516,7 +521,7 @@ mtw_attach(device_t self) struct usb_attach_arg *uaa = device_get_ivars(self); struct ieee80211com *ic = &sc->sc_ic; uint32_t ver; - int i, ret; + int i; uint32_t tmp; uint8_t iface_index; int ntries, error; @@ -536,7 +541,7 @@ mtw_attach(device_t self) DELAY(100000); /* 100ms settle time */ mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), - MTX_NETWORK_LOCK, MTX_DEF); + MTX_NETWORK_LOCK, MTX_DEF); iface_index = 0; @@ -595,8 +600,10 @@ mtw_attach(device_t self) sc->mac_rev = tmp & 0xffff; mtw_load_microcode(sc); - ret = msleep(&sc->fwloading, &sc->sc_mtx, 0, "fwload", 10 * hz); - if (ret == EWOULDBLOCK || sc->fwloading != 1) { + if (sc->fwloading != 1) + (void)msleep(&sc->fwloading, &sc->sc_mtx, 0, "fwload", + MTW_FWLOAD_TIMEOUT); + if (sc->fwloading != 1) { device_printf(sc->sc_dev, "timeout waiting for MCU to initialize\n"); goto detach; @@ -633,11 +640,11 @@ mtw_attach(device_t self) IEEE80211_C_WME | /* WME */ IEEE80211_C_WPA; /* WPA1|WPA2(RSN) */ device_printf(sc->sc_dev, "[HT] Enabling 802.11n\n"); - ic->ic_htcaps = IEEE80211_HTC_HT - | IEEE80211_HTC_AMPDU - | IEEE80211_HTC_AMSDU - | IEEE80211_HTCAP_MAXAMSDU_3839 - | IEEE80211_HTCAP_SMPS_OFF; + ic->ic_htcaps = IEEE80211_HTC_HT + | IEEE80211_HTC_AMPDU + | IEEE80211_HTC_AMSDU + | IEEE80211_HTCAP_MAXAMSDU_3839 + | IEEE80211_HTCAP_SMPS_OFF; ic->ic_rxstream = sc->nrxchains; ic->ic_txstream = sc->ntxchains; @@ -1106,6 +1113,7 @@ mtw_load_microcode(void *arg) struct mtw_softc *sc = (struct mtw_softc *)arg; const struct mtw_ucode_hdr *hdr; + const struct firmware *firmware_rom = NULL, *firmware = NULL; // onst struct mtw_ucode *fw = NULL; const char *fwname; size_t size; @@ -1113,47 +1121,43 @@ mtw_load_microcode(void *arg) uint32_t tmp, iofs = 0x40; // int ntries; int dlen, ilen; - device_printf(sc->sc_dev, "version:0x%hx\n", sc->asic_ver); - /* - * Firmware may still be running from a previous warm reboot. - * Force a reset of the MCU to ensure a clean state. - */ + MTW_DPRINTF(sc, MTW_DEBUG_FIRMWARE, "version:0x%hx\n", sc->asic_ver); + /* Check if MCU is already initialized and skip firmware reload */ mtw_read_cfg(sc, MTW_MCU_DMA_ADDR, &tmp); if (tmp == MTW_MCU_READY) { - device_printf(sc->sc_dev, "MCU already running, resetting\n"); - mtw_write(sc, MTW_MCU_RESET_CTL, MTW_RESET); - DELAY(10000); - mtw_write(sc, MTW_MCU_RESET_CTL, 0); - DELAY(10000); - /* Clear ready flag */ - mtw_write_cfg(sc, MTW_MCU_DMA_ADDR, 0); - DELAY(1000); + MTW_DPRINTF(sc, MTW_DEBUG_FIRMWARE, + "MCU already running, skipping firmware reload\n"); + sc->fwloading = 1; + wakeup(&sc->fwloading); + return; } if (sc->asic_ver == 0x7612) { fwname = "mtw-mt7662u_rom_patch"; - const struct firmware *firmware = firmware_get_flags(fwname,FIRMWARE_GET_NOWARN); - if (firmware == NULL) { + firmware_rom = firmware_get_flags(fwname, FIRMWARE_GET_NOWARN); + if (firmware_rom == NULL) { device_printf(sc->sc_dev, - "failed loadfirmware of file %s (error %d)\n", - fwname, error); + "failed to load firmware file %s\n", + fwname); return; } - size = firmware->datasize; + size = firmware_rom->datasize; const struct mtw_ucode *fw = (const struct mtw_ucode *) - firmware->data; + firmware_rom->data; hdr = (const struct mtw_ucode_hdr *)&fw->hdr; - // memcpy(fw,(const unsigned char*)firmware->data + - // 0x1e,size-0x1e); + // memcpy(fw,(const unsigned char*)firmware_rom->data + + // 0x1e,size-0x1e); ilen = size - 0x1e; mtw_ucode_setup(sc); - if ((error = mtw_ucode_write(sc, firmware->data, fw->ivb, ilen, - 0x90000)) != 0) { - goto fail; + if ((error = mtw_ucode_write(sc, firmware_rom->data, fw->ivb, + ilen, 0x90000)) != 0) { + device_printf(sc->sc_dev, + "Could not write ROM patch\n"); + goto fail_rom; } mtw_usb_dma_write(sc, 0x00e41814); } @@ -1170,13 +1174,15 @@ mtw_load_microcode(void *arg) // dofs = 0x80000; } MTW_UNLOCK(sc); - const struct firmware *firmware = firmware_get_flags(fwname, FIRMWARE_GET_NOWARN); + firmware = firmware_get_flags(fwname, FIRMWARE_GET_NOWARN); if (firmware == NULL) { device_printf(sc->sc_dev, - "failed loadfirmware of file %s (error %d)\n", fwname, - error); + "failed to load firmware file %s\n", + fwname); MTW_LOCK(sc); + if (firmware_rom != NULL) + firmware_put(firmware_rom, FIRMWARE_UNLOAD); return; } MTW_LOCK(sc); @@ -1213,11 +1219,21 @@ mtw_load_microcode(void *arg) device_printf(sc->sc_dev, "Could not write ucode errro=%d\n", error); - device_printf(sc->sc_dev, "loaded firmware ver %.8x %.8x %s\n", + MTW_DPRINTF(sc, MTW_DEBUG_FIRMWARE, + "loaded firmware ver %.8x %.8x %s\n", le32toh(hdr->fw_ver), le32toh(hdr->build_ver), hdr->build_time); + /* Release firmware objects */ + firmware_put(firmware, FIRMWARE_UNLOAD); + if (firmware_rom != NULL) + firmware_put(firmware_rom, FIRMWARE_UNLOAD); return; + fail: + firmware_put(firmware, FIRMWARE_UNLOAD); +fail_rom: + if (firmware_rom != NULL) + firmware_put(firmware_rom, FIRMWARE_UNLOAD); return; } static usb_error_t @@ -2868,12 +2884,13 @@ mtw_fw_callback(struct usb_xfer *xfer, usb_error_t error) } mtw_delay(sc, 10); - for (ntries = 0; ntries < 300; ntries++) { + for (ntries = 0; ntries < MTW_FW_READY_RETRIES; + ntries++) { if ((error = mtw_read_cfg(sc, MTW_MCU_DMA_ADDR, - &tmp)) != 0) { + &tmp)) != 0) { device_printf(sc->sc_dev, - "Could not read cfg error: %d\n", error); - + "Could not read cfg error: %d\n", + error); } if (tmp == MTW_MCU_READY) { MTW_DPRINTF(sc, MTW_DEBUG_FIRMWARE, @@ -2882,9 +2899,9 @@ mtw_fw_callback(struct usb_xfer *xfer, usb_error_t error) break; } - mtw_delay(sc, 30); + mtw_delay(sc, MTW_FW_READY_DELAY_MS); } - if (ntries == 300) + if (ntries == MTW_FW_READY_RETRIES) sc->fwloading = 0; wakeup(&sc->fwloading); return;