Message ID | af4d2d58-f567-4bdf-841b-8345d21f7035@gmail.com |
---|---|
State | New |
Headers | show |
Series | [rtw-next,1/2] wifi: rtw88: usb: Reduce control message timeout to 500 ms | expand |
: Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote: > RTL8811AU stops responding during the firmware download on some systems: > > [ 809.256440] rtw_8821au 5-2.1:1.0: Firmware version 42.4.0, H2C version 0 > [ 812.759142] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: renamed from wlan0 > [ 837.315388] rtw_8821au 1-4:1.0: write register 0x1ef4 failed with -110 > [ 867.524259] rtw_8821au 1-4:1.0: write register 0x1ef8 failed with -110 > [ 868.930976] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: entered promiscuous mode > [ 897.730952] rtw_8821au 1-4:1.0: write register 0x1efc failed with -110 > > Maybe it takes too long when writing the firmware 4 bytes at a time. > > Write 196 bytes at a time for RTL8821AU, RTL8811AU, and RTL8812AU, > and 254 bytes at a time for RTL8723DU. These are the sizes used in > their official drivers. Tested with all these chips. > > Cc: stable@vger.kernel.org > Link: https://github.com/lwfinger/rtw88/issues/344 > Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com> Acked-by: Ping-Ke Shih <pkshih@realtek.com> [..] > diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c > index b16db579fdce..ad15ce12ab7f 100644 > --- a/drivers/net/wireless/realtek/rtw88/usb.c > +++ b/drivers/net/wireless/realtek/rtw88/usb.c > @@ -165,6 +165,60 @@ static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) > rtw_usb_write(rtwdev, addr, val, 4); > } > > +static void rtw_usb_write_firmware_page(struct rtw_dev *rtwdev, u32 page, > + const u8 *data, u32 size) > +{ > + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); > + struct usb_device *udev = rtwusb->udev; > + u32 addr = FW_8192C_START_ADDRESS; FW_8192C_START_ADDRESS is existing already. But something like RTW_USB_FW_START_ADDRESS would be better. > + u8 *data_dup, *buf; > + u32 n, block_size; > + int ret; > + > + switch (rtwdev->chip->id) { > + case RTW_CHIP_TYPE_8723D: > + block_size = 254; > + break; > + default: > + block_size = 196; > + break; > + } > + > + data_dup = kmemdup(data, size, GFP_KERNEL); This is because type of argument `data` of usb_control_msg() is not const, right? Do you know if usb_control_msg() will actually modify the data?
On 08/05/2025 06:29, Ping-Ke Shih wrote: > : Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote: >> RTL8811AU stops responding during the firmware download on some systems: >> >> [ 809.256440] rtw_8821au 5-2.1:1.0: Firmware version 42.4.0, H2C version 0 >> [ 812.759142] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: renamed from wlan0 >> [ 837.315388] rtw_8821au 1-4:1.0: write register 0x1ef4 failed with -110 >> [ 867.524259] rtw_8821au 1-4:1.0: write register 0x1ef8 failed with -110 >> [ 868.930976] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: entered promiscuous mode >> [ 897.730952] rtw_8821au 1-4:1.0: write register 0x1efc failed with -110 >> >> Maybe it takes too long when writing the firmware 4 bytes at a time. >> >> Write 196 bytes at a time for RTL8821AU, RTL8811AU, and RTL8812AU, >> and 254 bytes at a time for RTL8723DU. These are the sizes used in >> their official drivers. Tested with all these chips. >> >> Cc: stable@vger.kernel.org >> Link: https://github.com/lwfinger/rtw88/issues/344 >> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com> > > Acked-by: Ping-Ke Shih <pkshih@realtek.com> > > [..] > >> diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c >> index b16db579fdce..ad15ce12ab7f 100644 >> --- a/drivers/net/wireless/realtek/rtw88/usb.c >> +++ b/drivers/net/wireless/realtek/rtw88/usb.c >> @@ -165,6 +165,60 @@ static void rtw_usb_write32(struct rtw_dev *rtwdev, u32 addr, u32 val) >> rtw_usb_write(rtwdev, addr, val, 4); >> } >> >> +static void rtw_usb_write_firmware_page(struct rtw_dev *rtwdev, u32 page, >> + const u8 *data, u32 size) >> +{ >> + struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); >> + struct usb_device *udev = rtwusb->udev; >> + u32 addr = FW_8192C_START_ADDRESS; > > FW_8192C_START_ADDRESS is existing already. But something like > RTW_USB_FW_START_ADDRESS would be better. > I agree, because rtw88 doesn't handle RTL8192C. There is FW_START_ADDR_LEGACY in fw.h. I must not have noticed it before. Should I send v2 for this? >> + u8 *data_dup, *buf; >> + u32 n, block_size; >> + int ret; >> + >> + switch (rtwdev->chip->id) { >> + case RTW_CHIP_TYPE_8723D: >> + block_size = 254; >> + break; >> + default: >> + block_size = 196; >> + break; >> + } >> + >> + data_dup = kmemdup(data, size, GFP_KERNEL); > > This is because type of argument `data` of usb_control_msg() is not const, right? > Do you know if usb_control_msg() will actually modify the data? > No, it's because usb_control_msg() rejects memory allocated by vmalloc(). I don't remember what error it printed. Maybe because the memory is not suitable for DMA.
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c index 204343ac2558..b16db579fdce 100644 --- a/drivers/net/wireless/realtek/rtw88/usb.c +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -139,7 +139,7 @@ static void rtw_usb_write(struct rtw_dev *rtwdev, u32 addr, u32 val, int len) ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RTW_USB_CMD_REQ, RTW_USB_CMD_WRITE, - addr, 0, data, len, 30000); + addr, 0, data, len, 500); if (ret < 0 && ret != -ENODEV && count++ < 4) rtw_err(rtwdev, "write register 0x%x failed with %d\n", addr, ret);
RTL8811AU stops responding during the firmware download on some systems: [ 809.256440] rtw_8821au 5-2.1:1.0: Firmware version 42.4.0, H2C version 0 [ 812.759142] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: renamed from wlan0 [ 837.315388] rtw_8821au 1-4:1.0: write register 0x1ef4 failed with -110 [ 867.524259] rtw_8821au 1-4:1.0: write register 0x1ef8 failed with -110 [ 868.930976] rtw_8821au 5-2.1:1.0 wlp48s0f4u2u1: entered promiscuous mode [ 897.730952] rtw_8821au 1-4:1.0: write register 0x1efc failed with -110 Each write takes 30 seconds to fail because that's the timeout currently used for control messages in rtw_usb_write(). In this scenario the firmware download takes at least 2000 seconds. Because this is done from the USB probe function, the long delay makes other things in the system hang. Reduce the timeout to 500 ms. This is the value used by the official USB wifi drivers from Realtek. Of course this only makes things hang for ~30 seconds instead of ~30 minutes. It doesn't fix the firmware download. Tested with RTL8822CU, RTL8812BU, RTL8811CU, RTL8814AU, RTL8811AU, RTL8812AU, RTL8821AU, RTL8723DU. Cc: stable@vger.kernel.org Fixes: a82dfd33d123 ("wifi: rtw88: Add common USB chip support") Link: https://github.com/lwfinger/rtw88/issues/344 Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com> --- drivers/net/wireless/realtek/rtw88/usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)