|
@@ -104,7 +104,8 @@
|
|
|
#define USB_TX_AGG 0xd40a
|
|
|
#define USB_RX_BUF_TH 0xd40c
|
|
|
#define USB_USB_TIMER 0xd428
|
|
|
-#define USB_RX_EARLY_AGG 0xd42c
|
|
|
+#define USB_RX_EARLY_TIMEOUT 0xd42c
|
|
|
+#define USB_RX_EARLY_SIZE 0xd42e
|
|
|
#define USB_PM_CTRL_STATUS 0xd432
|
|
|
#define USB_TX_DMA 0xd434
|
|
|
#define USB_TOLERANCE 0xd490
|
|
@@ -349,10 +350,10 @@
|
|
|
/* USB_MISC_0 */
|
|
|
#define PCUT_STATUS 0x0001
|
|
|
|
|
|
-/* USB_RX_EARLY_AGG */
|
|
|
-#define EARLY_AGG_SUPPER 0x0e832981
|
|
|
-#define EARLY_AGG_HIGH 0x0e837a12
|
|
|
-#define EARLY_AGG_SLOW 0x0e83ffff
|
|
|
+/* USB_RX_EARLY_TIMEOUT */
|
|
|
+#define COALESCE_SUPER 85000U
|
|
|
+#define COALESCE_HIGH 250000U
|
|
|
+#define COALESCE_SLOW 524280U
|
|
|
|
|
|
/* USB_WDT11_CTRL */
|
|
|
#define TIMER11_EN 0x0001
|
|
@@ -606,6 +607,7 @@ struct r8152 {
|
|
|
u32 saved_wolopts;
|
|
|
u32 msg_enable;
|
|
|
u32 tx_qlen;
|
|
|
+ u32 coalesce;
|
|
|
u16 ocp_base;
|
|
|
u8 *intr_buff;
|
|
|
u8 version;
|
|
@@ -2142,28 +2144,19 @@ static int rtl8152_enable(struct r8152 *tp)
|
|
|
return rtl_enable(tp);
|
|
|
}
|
|
|
|
|
|
-static void r8153_set_rx_agg(struct r8152 *tp)
|
|
|
+static void r8153_set_rx_early_timeout(struct r8152 *tp)
|
|
|
{
|
|
|
- u8 speed;
|
|
|
+ u32 ocp_data = tp->coalesce / 8;
|
|
|
|
|
|
- speed = rtl8152_get_speed(tp);
|
|
|
- if (speed & _1000bps) {
|
|
|
- if (tp->udev->speed == USB_SPEED_SUPER) {
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
|
|
|
- RX_THR_SUPPER);
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
|
|
|
- EARLY_AGG_SUPPER);
|
|
|
- } else {
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
|
|
|
- RX_THR_HIGH);
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
|
|
|
- EARLY_AGG_HIGH);
|
|
|
- }
|
|
|
- } else {
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_SLOW);
|
|
|
- ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
|
|
|
- EARLY_AGG_SLOW);
|
|
|
- }
|
|
|
+ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_TIMEOUT, ocp_data);
|
|
|
+}
|
|
|
+
|
|
|
+static void r8153_set_rx_early_size(struct r8152 *tp)
|
|
|
+{
|
|
|
+ u32 mtu = tp->netdev->mtu;
|
|
|
+ u32 ocp_data = (agg_buf_sz - mtu - VLAN_ETH_HLEN - VLAN_HLEN) / 4;
|
|
|
+
|
|
|
+ ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data);
|
|
|
}
|
|
|
|
|
|
static int rtl8153_enable(struct r8152 *tp)
|
|
@@ -2173,7 +2166,8 @@ static int rtl8153_enable(struct r8152 *tp)
|
|
|
|
|
|
set_tx_qlen(tp);
|
|
|
rtl_set_eee_plus(tp);
|
|
|
- r8153_set_rx_agg(tp);
|
|
|
+ r8153_set_rx_early_timeout(tp);
|
|
|
+ r8153_set_rx_early_size(tp);
|
|
|
|
|
|
return rtl_enable(tp);
|
|
|
}
|
|
@@ -3719,6 +3713,61 @@ out:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int rtl8152_get_coalesce(struct net_device *netdev,
|
|
|
+ struct ethtool_coalesce *coalesce)
|
|
|
+{
|
|
|
+ struct r8152 *tp = netdev_priv(netdev);
|
|
|
+
|
|
|
+ switch (tp->version) {
|
|
|
+ case RTL_VER_01:
|
|
|
+ case RTL_VER_02:
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ coalesce->rx_coalesce_usecs = tp->coalesce;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int rtl8152_set_coalesce(struct net_device *netdev,
|
|
|
+ struct ethtool_coalesce *coalesce)
|
|
|
+{
|
|
|
+ struct r8152 *tp = netdev_priv(netdev);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ switch (tp->version) {
|
|
|
+ case RTL_VER_01:
|
|
|
+ case RTL_VER_02:
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (coalesce->rx_coalesce_usecs > COALESCE_SLOW)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ ret = usb_autopm_get_interface(tp->intf);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ mutex_lock(&tp->control);
|
|
|
+
|
|
|
+ if (tp->coalesce != coalesce->rx_coalesce_usecs) {
|
|
|
+ tp->coalesce = coalesce->rx_coalesce_usecs;
|
|
|
+
|
|
|
+ if (netif_running(tp->netdev) && netif_carrier_ok(netdev))
|
|
|
+ r8153_set_rx_early_timeout(tp);
|
|
|
+ }
|
|
|
+
|
|
|
+ mutex_unlock(&tp->control);
|
|
|
+
|
|
|
+ usb_autopm_put_interface(tp->intf);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static struct ethtool_ops ops = {
|
|
|
.get_drvinfo = rtl8152_get_drvinfo,
|
|
|
.get_settings = rtl8152_get_settings,
|
|
@@ -3732,6 +3781,8 @@ static struct ethtool_ops ops = {
|
|
|
.get_strings = rtl8152_get_strings,
|
|
|
.get_sset_count = rtl8152_get_sset_count,
|
|
|
.get_ethtool_stats = rtl8152_get_ethtool_stats,
|
|
|
+ .get_coalesce = rtl8152_get_coalesce,
|
|
|
+ .set_coalesce = rtl8152_set_coalesce,
|
|
|
.get_eee = rtl_ethtool_get_eee,
|
|
|
.set_eee = rtl_ethtool_set_eee,
|
|
|
};
|
|
@@ -3783,6 +3834,7 @@ out:
|
|
|
static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
|
|
|
{
|
|
|
struct r8152 *tp = netdev_priv(dev);
|
|
|
+ int ret;
|
|
|
|
|
|
switch (tp->version) {
|
|
|
case RTL_VER_01:
|
|
@@ -3795,9 +3847,22 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu)
|
|
|
if (new_mtu < 68 || new_mtu > RTL8153_MAX_MTU)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ ret = usb_autopm_get_interface(tp->intf);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ mutex_lock(&tp->control);
|
|
|
+
|
|
|
dev->mtu = new_mtu;
|
|
|
|
|
|
- return 0;
|
|
|
+ if (netif_running(dev) && netif_carrier_ok(dev))
|
|
|
+ r8153_set_rx_early_size(tp);
|
|
|
+
|
|
|
+ mutex_unlock(&tp->control);
|
|
|
+
|
|
|
+ usb_autopm_put_interface(tp->intf);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static const struct net_device_ops rtl8152_netdev_ops = {
|
|
@@ -3966,6 +4031,18 @@ static int rtl8152_probe(struct usb_interface *intf,
|
|
|
tp->mii.reg_num_mask = 0x1f;
|
|
|
tp->mii.phy_id = R8152_PHY_ID;
|
|
|
|
|
|
+ switch (udev->speed) {
|
|
|
+ case USB_SPEED_SUPER:
|
|
|
+ tp->coalesce = COALESCE_SUPER;
|
|
|
+ break;
|
|
|
+ case USB_SPEED_HIGH:
|
|
|
+ tp->coalesce = COALESCE_HIGH;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ tp->coalesce = COALESCE_SLOW;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
intf->needs_remote_wakeup = 1;
|
|
|
|
|
|
tp->rtl_ops.init(tp);
|