|
@@ -24,7 +24,7 @@
|
|
#include <net/ip6_checksum.h>
|
|
#include <net/ip6_checksum.h>
|
|
|
|
|
|
/* Version Information */
|
|
/* Version Information */
|
|
-#define DRIVER_VERSION "v1.06.0 (2014/03/03)"
|
|
|
|
|
|
+#define DRIVER_VERSION "v1.06.1 (2014/10/01)"
|
|
#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
|
|
#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
|
|
#define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
|
|
#define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
|
|
#define MODULENAME "r8152"
|
|
#define MODULENAME "r8152"
|
|
@@ -1949,10 +1949,34 @@ static void rxdy_gated_en(struct r8152 *tp, bool enable)
|
|
ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
|
|
ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int rtl_start_rx(struct r8152 *tp)
|
|
|
|
+{
|
|
|
|
+ int i, ret = 0;
|
|
|
|
+
|
|
|
|
+ INIT_LIST_HEAD(&tp->rx_done);
|
|
|
|
+ for (i = 0; i < RTL8152_MAX_RX; i++) {
|
|
|
|
+ INIT_LIST_HEAD(&tp->rx_info[i].list);
|
|
|
|
+ ret = r8152_submit_rx(tp, &tp->rx_info[i], GFP_KERNEL);
|
|
|
|
+ if (ret)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int rtl_stop_rx(struct r8152 *tp)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < RTL8152_MAX_RX; i++)
|
|
|
|
+ usb_kill_urb(tp->rx_info[i].urb);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
static int rtl_enable(struct r8152 *tp)
|
|
static int rtl_enable(struct r8152 *tp)
|
|
{
|
|
{
|
|
u32 ocp_data;
|
|
u32 ocp_data;
|
|
- int i, ret;
|
|
|
|
|
|
|
|
r8152b_reset_packet_filter(tp);
|
|
r8152b_reset_packet_filter(tp);
|
|
|
|
|
|
@@ -1962,14 +1986,7 @@ static int rtl_enable(struct r8152 *tp)
|
|
|
|
|
|
rxdy_gated_en(tp, false);
|
|
rxdy_gated_en(tp, false);
|
|
|
|
|
|
- INIT_LIST_HEAD(&tp->rx_done);
|
|
|
|
- ret = 0;
|
|
|
|
- for (i = 0; i < RTL8152_MAX_RX; i++) {
|
|
|
|
- INIT_LIST_HEAD(&tp->rx_info[i].list);
|
|
|
|
- ret |= r8152_submit_rx(tp, &tp->rx_info[i], GFP_KERNEL);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return ret;
|
|
|
|
|
|
+ return rtl_start_rx(tp);
|
|
}
|
|
}
|
|
|
|
|
|
static int rtl8152_enable(struct r8152 *tp)
|
|
static int rtl8152_enable(struct r8152 *tp)
|
|
@@ -2053,8 +2070,7 @@ static void rtl_disable(struct r8152 *tp)
|
|
mdelay(1);
|
|
mdelay(1);
|
|
}
|
|
}
|
|
|
|
|
|
- for (i = 0; i < RTL8152_MAX_RX; i++)
|
|
|
|
- usb_kill_urb(tp->rx_info[i].urb);
|
|
|
|
|
|
+ rtl_stop_rx(tp);
|
|
|
|
|
|
rtl8152_nic_reset(tp);
|
|
rtl8152_nic_reset(tp);
|
|
}
|
|
}
|
|
@@ -2185,28 +2201,6 @@ static void rtl_phy_reset(struct r8152 *tp)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static void rtl_clear_bp(struct r8152 *tp)
|
|
|
|
-{
|
|
|
|
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
|
|
|
|
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_2, 0);
|
|
|
|
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_4, 0);
|
|
|
|
- ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_6, 0);
|
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_0, 0);
|
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_2, 0);
|
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_4, 0);
|
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_6, 0);
|
|
|
|
- mdelay(3);
|
|
|
|
- ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0);
|
|
|
|
- ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void r8153_clear_bp(struct r8152 *tp)
|
|
|
|
-{
|
|
|
|
- ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0);
|
|
|
|
- ocp_write_byte(tp, MCU_TYPE_USB, USB_BP_EN, 0);
|
|
|
|
- rtl_clear_bp(tp);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void r8153_teredo_off(struct r8152 *tp)
|
|
static void r8153_teredo_off(struct r8152 *tp)
|
|
{
|
|
{
|
|
u32 ocp_data;
|
|
u32 ocp_data;
|
|
@@ -2249,8 +2243,6 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
|
|
r8152_mdio_write(tp, MII_BMCR, data);
|
|
r8152_mdio_write(tp, MII_BMCR, data);
|
|
}
|
|
}
|
|
|
|
|
|
- rtl_clear_bp(tp);
|
|
|
|
-
|
|
|
|
set_bit(PHY_RESET, &tp->flags);
|
|
set_bit(PHY_RESET, &tp->flags);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2401,8 +2393,6 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
|
|
r8152_mdio_write(tp, MII_BMCR, data);
|
|
r8152_mdio_write(tp, MII_BMCR, data);
|
|
}
|
|
}
|
|
|
|
|
|
- r8153_clear_bp(tp);
|
|
|
|
-
|
|
|
|
if (tp->version == RTL_VER_03) {
|
|
if (tp->version == RTL_VER_03) {
|
|
data = ocp_reg_read(tp, OCP_EEE_CFG);
|
|
data = ocp_reg_read(tp, OCP_EEE_CFG);
|
|
data &= ~CTAP_SHORT_EN;
|
|
data &= ~CTAP_SHORT_EN;
|
|
@@ -3083,13 +3073,14 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
|
|
clear_bit(WORK_ENABLE, &tp->flags);
|
|
clear_bit(WORK_ENABLE, &tp->flags);
|
|
usb_kill_urb(tp->intr_urb);
|
|
usb_kill_urb(tp->intr_urb);
|
|
cancel_delayed_work_sync(&tp->schedule);
|
|
cancel_delayed_work_sync(&tp->schedule);
|
|
|
|
+ tasklet_disable(&tp->tl);
|
|
if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
|
|
if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
|
|
|
|
+ rtl_stop_rx(tp);
|
|
rtl_runtime_suspend_enable(tp, true);
|
|
rtl_runtime_suspend_enable(tp, true);
|
|
} else {
|
|
} else {
|
|
- tasklet_disable(&tp->tl);
|
|
|
|
tp->rtl_ops.down(tp);
|
|
tp->rtl_ops.down(tp);
|
|
- tasklet_enable(&tp->tl);
|
|
|
|
}
|
|
}
|
|
|
|
+ tasklet_enable(&tp->tl);
|
|
}
|
|
}
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -3108,17 +3099,18 @@ static int rtl8152_resume(struct usb_interface *intf)
|
|
if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
|
|
if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
|
|
rtl_runtime_suspend_enable(tp, false);
|
|
rtl_runtime_suspend_enable(tp, false);
|
|
clear_bit(SELECTIVE_SUSPEND, &tp->flags);
|
|
clear_bit(SELECTIVE_SUSPEND, &tp->flags);
|
|
|
|
+ set_bit(WORK_ENABLE, &tp->flags);
|
|
if (tp->speed & LINK_STATUS)
|
|
if (tp->speed & LINK_STATUS)
|
|
- tp->rtl_ops.disable(tp);
|
|
|
|
|
|
+ rtl_start_rx(tp);
|
|
} else {
|
|
} else {
|
|
tp->rtl_ops.up(tp);
|
|
tp->rtl_ops.up(tp);
|
|
rtl8152_set_speed(tp, AUTONEG_ENABLE,
|
|
rtl8152_set_speed(tp, AUTONEG_ENABLE,
|
|
tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
|
|
tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
|
|
DUPLEX_FULL);
|
|
DUPLEX_FULL);
|
|
|
|
+ tp->speed = 0;
|
|
|
|
+ netif_carrier_off(tp->netdev);
|
|
|
|
+ set_bit(WORK_ENABLE, &tp->flags);
|
|
}
|
|
}
|
|
- tp->speed = 0;
|
|
|
|
- netif_carrier_off(tp->netdev);
|
|
|
|
- set_bit(WORK_ENABLE, &tp->flags);
|
|
|
|
usb_submit_urb(tp->intr_urb, GFP_KERNEL);
|
|
usb_submit_urb(tp->intr_urb, GFP_KERNEL);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3405,7 +3397,7 @@ static void rtl8153_unload(struct r8152 *tp)
|
|
if (test_bit(RTL8152_UNPLUG, &tp->flags))
|
|
if (test_bit(RTL8152_UNPLUG, &tp->flags))
|
|
return;
|
|
return;
|
|
|
|
|
|
- r8153_power_cut_en(tp, true);
|
|
|
|
|
|
+ r8153_power_cut_en(tp, false);
|
|
}
|
|
}
|
|
|
|
|
|
static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
|
|
static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
|
|
@@ -3558,7 +3550,11 @@ static void rtl8152_disconnect(struct usb_interface *intf)
|
|
|
|
|
|
usb_set_intfdata(intf, NULL);
|
|
usb_set_intfdata(intf, NULL);
|
|
if (tp) {
|
|
if (tp) {
|
|
- set_bit(RTL8152_UNPLUG, &tp->flags);
|
|
|
|
|
|
+ struct usb_device *udev = tp->udev;
|
|
|
|
+
|
|
|
|
+ if (udev->state == USB_STATE_NOTATTACHED)
|
|
|
|
+ set_bit(RTL8152_UNPLUG, &tp->flags);
|
|
|
|
+
|
|
tasklet_kill(&tp->tl);
|
|
tasklet_kill(&tp->tl);
|
|
unregister_netdev(tp->netdev);
|
|
unregister_netdev(tp->netdev);
|
|
tp->rtl_ops.unload(tp);
|
|
tp->rtl_ops.unload(tp);
|