From nobody Wed Jun 17 14:39:13 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 4ggRMC11lCz6hS05 for ; Wed, 17 Jun 2026 14:39:19 +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 "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4ggRMB1MFgz40NL for ; Wed, 17 Jun 2026 14:39:18 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1781707158; 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=YzrYvZgX3FOyYhVhfURQSluKMi9+Dft1vYs+DrUNzyU=; b=wcBUGYmRQr6v0QI/NHgMADmWURLAYnSwWEc/g3/b/MewaAmhaSCSWFVX7AvZsQxIKYe262 exCb8BUE3hu6NTuy3YXT9eVuKsLDv1CFzJyKVtrWgv33LuYZ88V3Wq9avsk9pBqRJeAOYL 1sF2NtxYTLkGu7Z67oc1LYYtqRPmAumF10mJWdabhHMsuQ3EG6NYONbm4fSXHgxxB0U5P9 wH7tTNv1L0gefxqwPR59TCI+dpaFfAJYtK3kjoZrCBr/ZvMeisuZOBJbJqu6nxu9Z0EgP+ IxEADBiijAbuw1VH46QqyELeJM/RavjK/cvHNfIv51PCDpFta6k6lxtGuj1TuA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1781707158; a=rsa-sha256; cv=none; b=xdfuFYnv03aKzhqiSY1Vvs5nBfx9PNNLzPQS3BHybbpidFDEpxEPiL6uSzpmHj27Piha18 A9nNasWZ3al5GOYYWwzty0gouGwPyymhxD0lHhIaVTE//n/Y8mXv4UiUz+AagMyGtBL1qT Tr5JniAQHY+OZjmbDmrSGWiEKFHcDmX1uUhDMaOrnLyPS3WsxqZTWIYcXWCxbE2l6OL/Qu XbzMhvC76chcuREieMXwpUnlsLVcg9dSXetXoERhdlkM0wK2VzY8ykPdKaW28XQAn6gReu o7y2CSrCEqw9PeBQk9qRyt5EiCiCOTxhw4Bm9xiw3YwpccNAThPbe9pkHONY4w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1781707158; 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=YzrYvZgX3FOyYhVhfURQSluKMi9+Dft1vYs+DrUNzyU=; b=S7j7yFTWVUWjUU4usLNA+XLSLTtt2jysn0Z3TW+YdYLR2Ct4CFVFXZu4lyNsSVwXzPfC1B OYXXjX4wD9sOh8BFMS1+sYEXgigUgC9vCj9EF9kCs5+x9bHTrz3ytRJZ4BTS1+BJdatAOE zr4HjSqHu5PJMr9CdylJcsBEnV+l4mcPnbzPxYjZTQ6rNGnq8oZHROQl7iwRCZJoJMlUsV h4ZCQHzWn6YWioRhBG9nZYGr67iJ16/ZG/IAych7f4ol3HUKh/g7v3GZikEoCbiDZIFnkJ pGTg+Pb0MK1jgsWPaW6jlLXRDtywvfXL7TEH2JSnUAIDaHGHFRhxnX7zI6e8fQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4ggRMB0rnYz1bB for ; Wed, 17 Jun 2026 14:39:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3acc4 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 17 Jun 2026 14:39:13 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Abdelkader Boudih From: Adrian Chadd Subject: git: f981fa12b760 - main - mtw: Fix firmware loading and memory leaks 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: adrian X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f981fa12b760a5f0983eeec8065a4dec5295ab24 Auto-Submitted: auto-generated Date: Wed, 17 Jun 2026 14:39:13 +0000 Message-Id: <6a32b191.3acc4.25da149a@gitrepo.freebsd.org> The branch main has been updated by adrian: URL: https://cgit.FreeBSD.org/src/commit/?id=f981fa12b760a5f0983eeec8065a4dec5295ab24 commit f981fa12b760a5f0983eeec8065a4dec5295ab24 Author: Abdelkader Boudih AuthorDate: 2026-06-17 14:30:21 +0000 Commit: Adrian Chadd CommitDate: 2026-06-17 14:39:09 +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 --- 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 9d256056f6b2..5eaa31267b42 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; @@ -1107,6 +1114,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; @@ -1114,47 +1122,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); } @@ -1171,13 +1175,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); @@ -1214,11 +1220,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 @@ -2877,12 +2893,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, @@ -2891,9 +2908,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;