RE: [PATCH rtw-next v2] wifi: rtw88: usb: do not log transfers lost to a mode switch

Ping-Ke Shih <[email protected]>
Newsgroups org.kernel.vger.linux-wireless,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Mehmet Fide <[email protected]> wrote:
> An RTL8822BU or RTL8822CU is asked to come back as a USB 3 device by
> rtw_usb_switch_mode_new(). The chip powers off its MAC and leaves the bus
> while the last control transfers of that sequence are still in flight, so
> they complete with -EPROTO and the driver reports them as errors:
> 
>   rtw_8822bu 1-1:1.0: Firmware version 27.2.0, H2C version 13
>   rtw_8822bu 1-1:1.0: write register 0xc4 failed with -71
>   usb 1-1: USB disconnect, device number 2
>   usbcore: registered new interface driver rtw_8822bu
>   rtw_8822bu 1-1:1.0: Firmware version 27.2.0, H2C version 13
> 
> Register 0xc4 is REG_PAD_CTRL2 and the access losing the race is the
> rtw_write32_set() that ends the switch sequence, a few milliseconds before
> the disconnect. Which transfer gets caught varies from boot to boot: 0xc4
> is in the "always on" section, so every write to it is followed by a second
> one from rtw_usb_reg_sec(), and sometimes that is the one that fails:
> 
>   rtw_8822bu 1-1:1.0: rtw_usb_reg_sec: reg 0x4e0, usb write 1 fail, status: -71

How about changing to use WARN_ONCE()?

[...]

> @@ -1098,6 +1098,7 @@ static int rtw_usb_switch_mode_old(struct rtw_dev *rtwdev)
>                         rtw_write8(rtwdev, REG_ACLK_MON, 0x1);
>                         rtw_write8(rtwdev, 0x3d, 0x3);
>                         /* usb disconnect */
> +                       rtwusb->switching_mode = true;
>                         rtw_write8(rtwdev, REG_SYS_PW_CTRL + 1, 0x80);
>                         return 1;
>                 }

[...]

> @@ -1151,6 +1153,11 @@ static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev)
>         rtw_write32(rtwdev, REG_PAD_CTRL2, pad_ctrl2);
>         rtw_write8(rtwdev, REG_PAD_CTRL2 + 1, 4);
> 
> +       /* From here the chip powers off its MAC and re-enumerates, so it can
> +        * leave the bus while a control transfer is still in flight.
> +        */
> +       rtwusb->switching_mode = true;
> +
>         rtw_write16_set(rtwdev, REG_SYS_PW_CTRL, BIT_APFM_OFFMAC);
>         usleep_range(1000, 1001);
>         rtw_write32_set(rtwdev, REG_PAD_CTRL2, BIT_NO_PDN_CHIPOFF_V1);

If WARN_ONCE isn't suitable, move these two assignments to caller.
I think only set `rtwusb->switching_mode = true` only if the return
value is 1.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.