Skip to content

Commit 0d3b9c2

Browse files
hayesorzgregkh
authored andcommitted
r8152: fix rx issue for runtime suspend
[ Upstream commit 75dc692eda114cb234a46cb11893a9c3ea520934 ] Pause the rx and make sure the rx fifo is empty when the autosuspend occurs. If the rx data comes when the driver is canceling the rx urb, the host controller would stop getting the data from the device and continue it after next rx urb is submitted. That is, one continuing data is split into two different urb buffers. That let the driver take the data as a rx descriptor, and unexpected behavior happens. Signed-off-by: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent c31a3c7 commit 0d3b9c2

1 file changed

Lines changed: 28 additions & 3 deletions

File tree

drivers/net/usb/r8152.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3452,17 +3452,42 @@ static int rtl8152_rumtime_suspend(struct r8152 *tp)
34523452
int ret = 0;
34533453

34543454
if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) {
3455+
u32 rcr = 0;
3456+
34553457
if (delay_autosuspend(tp)) {
34563458
ret = -EBUSY;
34573459
goto out1;
34583460
}
34593461

3462+
if (netif_carrier_ok(netdev)) {
3463+
u32 ocp_data;
3464+
3465+
rcr = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
3466+
ocp_data = rcr & ~RCR_ACPT_ALL;
3467+
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
3468+
rxdy_gated_en(tp, true);
3469+
ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA,
3470+
PLA_OOB_CTRL);
3471+
if (!(ocp_data & RXFIFO_EMPTY)) {
3472+
rxdy_gated_en(tp, false);
3473+
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr);
3474+
ret = -EBUSY;
3475+
goto out1;
3476+
}
3477+
}
3478+
34603479
clear_bit(WORK_ENABLE, &tp->flags);
34613480
usb_kill_urb(tp->intr_urb);
3462-
napi_disable(&tp->napi);
3463-
rtl_stop_rx(tp);
3481+
34643482
rtl_runtime_suspend_enable(tp, true);
3465-
napi_enable(&tp->napi);
3483+
3484+
if (netif_carrier_ok(netdev)) {
3485+
napi_disable(&tp->napi);
3486+
rtl_stop_rx(tp);
3487+
rxdy_gated_en(tp, false);
3488+
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr);
3489+
napi_enable(&tp->napi);
3490+
}
34663491
}
34673492

34683493
set_bit(SELECTIVE_SUSPEND, &tp->flags);

0 commit comments

Comments
 (0)