From nobody Sat May 30 12:38:21 2026 Received: from out-171.mta0.migadu.com (out-171.mta0.migadu.com [91.218.175.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D89036F43F for ; Fri, 8 May 2026 05:44:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778219091; cv=none; b=WXfj9adejh8nvI/DUmI3QT8PaqnQA7zNufnbUi2w8YzG+nnZRIxr41yNYcumM9QlXJlZYkruWDii/ZQe8TnamjULIulZneaGjZ1l7vTF8zZcJocnH/AAteOCBefyp/rjIoCfNtfjdzecRgIch8yliyjvkVvTTpI3YCkqtlNHKwI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778219091; c=relaxed/simple; bh=A/Fj+NFOPcUtK+kbHgS4pzM5XLYsm/Hze0cqyL9ImZY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bkzXYN52WypW+f0TfyhoMe+hv37IEGQpE6Y2UypU0VM9iSgYpMnNKSpTiOFmiqrXB0EqxRbF49JYFtUoOIzP4fz9nYEyUuZ1U0rukQxWzliTQs/R9Z6H7fUUCS+4FvLhpteSI2CbJCZ0WVOE5u+I/So0KG7QbF5csAyAXUVe7mg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=justthetip.ca; spf=pass smtp.mailfrom=justthetip.ca; dkim=pass (2048-bit key) header.d=justthetip.ca header.i=@justthetip.ca header.b=Y5uXiDNR; arc=none smtp.client-ip=91.218.175.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=justthetip.ca Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=justthetip.ca Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=justthetip.ca header.i=@justthetip.ca header.b="Y5uXiDNR" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=justthetip.ca; s=key1; t=1778219070; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RMo8rsH9EAVl21A/VusLdNr6UnE6XSL7Qp9X5I4tchE=; b=Y5uXiDNR8QlOXkfEMfjSXgqJQK1gtgjopXutdrqZ9fURbK+ZnfmOeiQLCirIAyusAE4Jl6 2TLu7gcpnCq+krUA35koJJkNYFLfUqWPBFYj5cG19nR5sOrEeUJX205YIjXx0LeBQBhipt LvDJJiK4gV9MuZ6VzknS6+NUyNLU4vADMVyF2I7u6PJDN5gnHpOcFpd2RSJBE+gapmVPsm fgZp4uX6QDmyB4G1Odi/87uvkcoNeBjE8sDBGOiOJq4GQhsQvZFFtLiB0qlY1Hqdxc10cJ Kz1b9OODZ/Kd5FD+z8rKRPTAgIGCV5OxROX+1GV+ZmItuDCeSEDmIbsFD9dTIg== From: Lucid Duck To: linux-wireless@vger.kernel.org Cc: Ping-Ke Shih , Bitterblue Smith , linux-kernel@vger.kernel.org, Devin Wittmayer Subject: [PATCH 1/1] wifi: rtw89: usb: Support switching to USB 3 mode Date: Thu, 7 May 2026 22:44:21 -0700 Message-ID: <20260508054421.128938-2-lucid_duck@justthetip.ca> In-Reply-To: <20260508054421.128938-1-lucid_duck@justthetip.ca> References: <20260508054421.128938-1-lucid_duck@justthetip.ca> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: Bitterblue Smith The Realtek wifi 6/7 devices which support USB 3 are weird: when first plugged in, they pretend to be USB 2. The driver needs to send some commands to the device, which make it disappear and come back as a USB 3 device. Implement the required commands in rtw89. When a USB 3 device is plugged into a USB 2 port, rtw89 will try to switch it to USB 3 mode only once. The device will disappear and come back still in USB 2 mode, of course. Some people experience heavy interference in the 2.4 GHz band in USB 3 mode, so add a module parameter switch_usb_mode with the default value 1 to let people disable the switching. Tested with RTL8832BU and RTL8832CU. Signed-off-by: Bitterblue Smith Signed-off-by: Devin Wittmayer Tested-by: Devin Wittmayer --- drivers/net/wireless/realtek/rtw89/reg.h | 4 +++ drivers/net/wireless/realtek/rtw89/usb.c | 41 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireles= s/realtek/rtw89/reg.h index 42ffe83931a3..7d4c085d9fb2 100644 --- a/drivers/net/wireless/realtek/rtw89/reg.h +++ b/drivers/net/wireless/realtek/rtw89/reg.h @@ -164,6 +164,10 @@ #define R_AX_DBG_PORT_SEL 0x00C0 #define B_AX_DEBUG_ST_MASK GENMASK(31, 0) =20 +#define R_AX_PAD_CTRL2 0x00C4 +#define U2SWITCHU3 0xB +#define USB_SWITCH_DELAY 0xF + #define R_AX_PMC_DBG_CTRL2 0x00CC #define B_AX_SYSON_DIS_PMCR_AX_WRMSK BIT(2) =20 diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireles= s/realtek/rtw89/usb.c index 767a95f759b1..4fb25791d118 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.c +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -9,6 +9,11 @@ #include "txrx.h" #include "usb.h" =20 +static bool rtw89_switch_usb_mode =3D true; +module_param_named(switch_usb_mode, rtw89_switch_usb_mode, bool, 0644); +MODULE_PARM_DESC(switch_usb_mode, + "Set to N to disable switching to USB 3 mode to avoid potential interfe= rence in the 2.4 GHz band (default: Y)"); + static void rtw89_usb_read_port_complete(struct urb *urb); =20 static void rtw89_usb_vendorreq(struct rtw89_dev *rtwdev, u32 addr, @@ -1027,6 +1032,35 @@ static void rtw89_usb_intf_deinit(struct rtw89_dev *= rtwdev, usb_set_intfdata(intf, NULL); } =20 +static int rtw89_usb_switch_mode(struct rtw89_dev *rtwdev) +{ + struct rtw89_usb *rtwusb =3D rtw89_usb_priv(rtwdev); + + if (!rtw89_switch_usb_mode) + return 0; + + /* No known USB 3 devices with this chip. */ + if (rtwdev->chip->chip_id =3D=3D RTL8851B) + return 0; + + if (rtwusb->udev->speed =3D=3D USB_SPEED_SUPER) + return 0; + + rtw89_debug(rtwdev, RTW89_DBG_HCI, "%s: pad_ctrl2: %#x %#x\n", + __func__, + rtw89_read8(rtwdev, R_AX_PAD_CTRL2 + 1), + rtw89_read8(rtwdev, R_AX_PAD_CTRL2 + 2)); + + /* Already tried to switch but it's a USB 2 port. */ + if (rtw89_read8(rtwdev, R_AX_PAD_CTRL2 + 1) =3D=3D USB_SWITCH_DELAY) + return 0; + + rtw89_write8(rtwdev, R_AX_PAD_CTRL2 + 1, USB_SWITCH_DELAY); + rtw89_write8(rtwdev, R_AX_PAD_CTRL2 + 2, U2SWITCHU3); + + return 1; +} + int rtw89_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1059,6 +1093,13 @@ int rtw89_usb_probe(struct usb_interface *intf, goto err_free_hw; } =20 + ret =3D rtw89_usb_switch_mode(rtwdev); + if (ret) { + /* Not a fail, but we do need to skip rtw89_core_register. */ + ret =3D 0; + goto err_intf_deinit; + } + if (rtwusb->udev->speed =3D=3D USB_SPEED_SUPER) rtwdev->hci.dle_type =3D RTW89_HCI_DLE_TYPE_USB3; else --=20 2.53.0