r8152: fix rx issue for runtime suspend
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>
This commit is contained in:
parent
8fb2806168
commit
75dc692eda
|
@ -3582,17 +3582,42 @@ static int rtl8152_rumtime_suspend(struct r8152 *tp)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) {
|
if (netif_running(netdev) && test_bit(WORK_ENABLE, &tp->flags)) {
|
||||||
|
u32 rcr = 0;
|
||||||
|
|
||||||
if (delay_autosuspend(tp)) {
|
if (delay_autosuspend(tp)) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto out1;
|
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);
|
clear_bit(WORK_ENABLE, &tp->flags);
|
||||||
usb_kill_urb(tp->intr_urb);
|
usb_kill_urb(tp->intr_urb);
|
||||||
napi_disable(&tp->napi);
|
|
||||||
rtl_stop_rx(tp);
|
|
||||||
tp->rtl_ops.autosuspend_en(tp, true);
|
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);
|
set_bit(SELECTIVE_SUSPEND, &tp->flags);
|
||||||
|
|
Loading…
Reference in New Issue