Commit 66f24d62 authored by hayeswang's avatar hayeswang Committed by Greg Kroah-Hartman

r8152: fix rx issue for runtime suspend

[ Upstream commit 75dc692e ]

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: default avatarHayes Wang <hayeswang@realtek.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c8a89b4f
......@@ -3582,17 +3582,42 @@ static int rtl8152_rumtime_suspend(struct r8152 *tp)
int ret = 0;
if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) {
u32 rcr = 0;
if (delay_autosuspend(tp)) {
ret = -EBUSY;
goto out1;
}
if (netif_carrier_ok(netdev)) {
u32 ocp_data;
rcr = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
ocp_data = rcr & ~RCR_ACPT_ALL;
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
rxdy_gated_en(tp, true);
ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA,
PLA_OOB_CTRL);
if (!(ocp_data & RXFIFO_EMPTY)) {
rxdy_gated_en(tp, false);
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr);
ret = -EBUSY;
goto out1;
}
}
clear_bit(WORK_ENABLE, &tp->flags);
usb_kill_urb(tp->intr_urb);
napi_disable(&tp->napi);
rtl_stop_rx(tp);
tp->rtl_ops.autosuspend_en(tp, true);
napi_enable(&tp->napi);
if (netif_carrier_ok(netdev)) {
napi_disable(&tp->napi);
rtl_stop_rx(tp);
rxdy_gated_en(tp, false);
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, rcr);
napi_enable(&tp->napi);
}
}
set_bit(SELECTIVE_SUSPEND, &tp->flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment