Skip to content

Commit 8ceda6d

Browse files
hayesorzdavem330
authored andcommitted
r8152: fix flow control issue of RTL8156A
The feature of flow control becomes abnormal, if the device sends a pause frame and the tx/rx is disabled before sending a release frame. It causes the lost of packets. Set PLA_RX_FIFO_FULL and PLA_RX_FIFO_EMPTY to zeros before disabling the tx/rx. And, toggle FC_PATCH_TASK before enabling tx/rx to reset the flow control patch and timer. Then, the hardware could clear the state and the flow control becomes normal after enabling tx/rx. Besides, remove inline for fc_pause_on_auto() and fc_pause_off_auto(). Fixes: 195aae3 ("r8152: support new chips") Signed-off-by: Hayes Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 526f28b commit 8ceda6d

File tree

1 file changed

+36
-20
lines changed

1 file changed

+36
-20
lines changed

drivers/net/usb/r8152.c

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5986,6 +5986,25 @@ static void rtl8153_disable(struct r8152 *tp)
59865986
r8153_aldps_en(tp, true);
59875987
}
59885988

5989+
static u32 fc_pause_on_auto(struct r8152 *tp)
5990+
{
5991+
return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024);
5992+
}
5993+
5994+
static u32 fc_pause_off_auto(struct r8152 *tp)
5995+
{
5996+
return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024);
5997+
}
5998+
5999+
static void r8156_fc_parameter(struct r8152 *tp)
6000+
{
6001+
u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp);
6002+
u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp);
6003+
6004+
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16);
6005+
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16);
6006+
}
6007+
59896008
static int rtl8156_enable(struct r8152 *tp)
59906009
{
59916010
u32 ocp_data;
@@ -5994,6 +6013,7 @@ static int rtl8156_enable(struct r8152 *tp)
59946013
if (test_bit(RTL8152_UNPLUG, &tp->flags))
59956014
return -ENODEV;
59966015

6016+
r8156_fc_parameter(tp);
59976017
set_tx_qlen(tp);
59986018
rtl_set_eee_plus(tp);
59996019
r8153_set_rx_early_timeout(tp);
@@ -6025,9 +6045,24 @@ static int rtl8156_enable(struct r8152 *tp)
60256045
ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data);
60266046
}
60276047

6048+
ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK);
6049+
ocp_data &= ~FC_PATCH_TASK;
6050+
ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data);
6051+
usleep_range(1000, 2000);
6052+
ocp_data |= FC_PATCH_TASK;
6053+
ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data);
6054+
60286055
return rtl_enable(tp);
60296056
}
60306057

6058+
static void rtl8156_disable(struct r8152 *tp)
6059+
{
6060+
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 0);
6061+
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 0);
6062+
6063+
rtl8153_disable(tp);
6064+
}
6065+
60316066
static int rtl8156b_enable(struct r8152 *tp)
60326067
{
60336068
u32 ocp_data;
@@ -6429,25 +6464,6 @@ static void rtl8153c_up(struct r8152 *tp)
64296464
r8153b_u1u2en(tp, true);
64306465
}
64316466

6432-
static inline u32 fc_pause_on_auto(struct r8152 *tp)
6433-
{
6434-
return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024);
6435-
}
6436-
6437-
static inline u32 fc_pause_off_auto(struct r8152 *tp)
6438-
{
6439-
return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024);
6440-
}
6441-
6442-
static void r8156_fc_parameter(struct r8152 *tp)
6443-
{
6444-
u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp);
6445-
u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp);
6446-
6447-
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16);
6448-
ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16);
6449-
}
6450-
64516467
static void rtl8156_change_mtu(struct r8152 *tp)
64526468
{
64536469
u32 rx_max_size = mtu_to_size(tp->netdev->mtu);
@@ -9340,7 +9356,7 @@ static int rtl_ops_init(struct r8152 *tp)
93409356
case RTL_VER_10:
93419357
ops->init = r8156_init;
93429358
ops->enable = rtl8156_enable;
9343-
ops->disable = rtl8153_disable;
9359+
ops->disable = rtl8156_disable;
93449360
ops->up = rtl8156_up;
93459361
ops->down = rtl8156_down;
93469362
ops->unload = rtl8153_unload;

0 commit comments

Comments
 (0)