diff --git a/Makefile b/Makefile index 5d03b8f..15e749d 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=r8152 -PKG_VERSION:=2.16.3 +PKG_VERSION:=2.17.1 PKG_RELEASE:=1 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) diff --git a/patches/020-6.1-support.patch b/patches/020-6.1-support.patch deleted file mode 100644 index 756aba5..0000000 --- a/patches/020-6.1-support.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- a/compatibility.h -+++ b/compatibility.h -@@ -237,9 +237,15 @@ - #define napi_disable(napi_ptr) netif_poll_disable(container_of(napi_ptr, struct r8152, napi)->netdev) - #define napi_schedule(napi_ptr) netif_rx_schedule(container_of(napi_ptr, struct r8152, napi)->netdev) - #define napi_complete(napi_ptr) netif_rx_complete(container_of(napi_ptr, struct r8152, napi)->netdev) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) -+ #define netif_napi_add_weight(ndev, napi_ptr, function, weight_t) \ -+ ndev->poll = function; \ -+ ndev->weight = weight_t; -+#else - #define netif_napi_add(ndev, napi_ptr, function, weight_t) \ - ndev->poll = function; \ - ndev->weight = weight_t; -+#endif - typedef unsigned long uintptr_t; - #define DMA_BIT_MASK(value) \ - (value < 64 ? ((1ULL << value) - 1) : 0xFFFFFFFFFFFFFFFFULL) ---- a/r8152.c -+++ b/r8152.c -@@ -20718,10 +20718,17 @@ - - usb_set_intfdata(intf, tp); - -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) -+ if (tp->support_2500full) -+ netif_napi_add_weight(netdev, &tp->napi, r8152_poll, 256); -+ else -+ netif_napi_add_weight(netdev, &tp->napi, r8152_poll, 64); -+#else - if (tp->support_2500full) - netif_napi_add(netdev, &tp->napi, r8152_poll, 256); - else - netif_napi_add(netdev, &tp->napi, r8152_poll, 64); -+#endif - - ret = register_netdev(netdev); - if (ret != 0) { diff --git a/patches/100-add-LED-configuration-from-OF.patch b/patches/100-add-LED-configuration-from-OF.patch index 8e18ee5..9983092 100644 --- a/patches/100-add-LED-configuration-from-OF.patch +++ b/patches/100-add-LED-configuration-from-OF.patch @@ -12,6 +12,8 @@ Signed-off-by: David Bauer r8152.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) +diff --git a/r8152.c b/r8152.c +index 5d6df58..40b7d17 100644 --- a/r8152.c +++ b/r8152.c @@ -18,6 +18,7 @@ @@ -22,7 +24,7 @@ Signed-off-by: David Bauer #include #include #include -@@ -10107,6 +10108,22 @@ static void rtl_disable_spi(struct r8152 +@@ -10413,6 +10414,22 @@ static void rtl_disable_spi(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_USB, 0xcbf0, ocp_data); } @@ -45,7 +47,7 @@ Signed-off-by: David Bauer static void r8152b_init(struct r8152 *tp) { u32 ocp_data; -@@ -10168,6 +10185,8 @@ static void r8152b_init(struct r8152 *tp +@@ -10476,6 +10493,8 @@ static void r8152b_init(struct r8152 *tp) ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); ocp_write_word(tp, MCU_TYPE_USB, USB_USB_CTRL, ocp_data); @@ -54,7 +56,7 @@ Signed-off-by: David Bauer } static void r8153_init(struct r8152 *tp) -@@ -10311,6 +10330,8 @@ static void r8153_init(struct r8152 *tp) +@@ -10613,6 +10632,8 @@ static void r8153_init(struct r8152 *tp) tp->coalesce = COALESCE_SLOW; break; } @@ -63,7 +65,7 @@ Signed-off-by: David Bauer } static void r8153b_init(struct r8152 *tp) -@@ -10413,6 +10434,8 @@ static void r8153b_init(struct r8152 *tp +@@ -10705,6 +10726,8 @@ static void r8153b_init(struct r8152 *tp) rtl_tally_reset(tp); tp->coalesce = 15000; /* 15 us */ @@ -72,3 +74,6 @@ Signed-off-by: David Bauer } static void r8153c_init(struct r8152 *tp) +-- +2.34.8 + diff --git a/patches/200-fix-for-linux-5.19-without-breaking-older-kernel.patch b/patches/200-fix-for-linux-5.19-without-breaking-older-kernel.patch deleted file mode 100644 index 7b9e117..0000000 --- a/patches/200-fix-for-linux-5.19-without-breaking-older-kernel.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 6ffb3760c34a904467d70830ac9c10211e8f5d3a Mon Sep 17 00:00:00 2001 -From: Hyacinthe Cartiaux -Date: Wed, 14 Sep 2022 15:13:31 +0200 -Subject: [PATCH] Fix for linux 5.19 without breaking older kernel - compatibility - ---- - r8152.c | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/r8152.c b/r8152.c -index 9c2bd16..5391b21 100644 ---- a/r8152.c -+++ b/r8152.c -@@ -20458,9 +20458,13 @@ static ssize_t sg_en_store(struct device *dev, struct device_attribute *attr, - return -EINVAL; - } - --#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) -+/* LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) */ -+ netif_set_tso_max_size(netdev, tso_size); -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -+/* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */ - netif_set_gso_max_size(netdev, tso_size); --#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */ -+#endif - - return count; - } -@@ -20620,12 +20624,16 @@ static int rtl8152_probe(struct usb_interface *intf, - rtl_get_mapt_ver(tp); - - netdev->ethtool_ops = &ops; --#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) -+/* LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) */ -+ netif_set_tso_max_size(netdev, RTL_LIMITED_TSO_SIZE); -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) -+/* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */ - if (!tp->sg_use) - netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); - #else - netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); --#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */ -+#endif - - #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) - /* MTU range: 68 - 1500 or 9194 */ diff --git a/src/ReadMe.txt b/src/ReadMe.txt index dd91246..78d07e6 100644 --- a/src/ReadMe.txt +++ b/src/ReadMe.txt @@ -39,3 +39,20 @@ Changes the number of ring entries for the Rx ring. # ethtool -G eth0 rx 100 + +- Tunable parameters + + Get the current rx copybreak value in bytes. + # ethtool --get-tunable eth0 rx-copybreak + + Set the rx copybreak value in bytes. + # ethtool --set-tunable eth0 rx-copybreak 256 + +- Flow control + + Queries the specified Ethernet device for pause parameter information. + # ethtool -a eth0 + + Changes the pause parameters of the specified Ethernet device. + # ethtool -A eth0 rx off tx off (Disable flow control) + # ethtool -A eth0 rx on tx off (Enable flow control) diff --git a/src/compatibility.h b/src/compatibility.h index 7738d17..d1e044d 100644 --- a/src/compatibility.h +++ b/src/compatibility.h @@ -21,6 +21,10 @@ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0) */ #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0) + #define TSO_LEGACY_MAX_SIZE 65536 + #define netif_napi_add_weight netif_napi_add + #define netif_set_tso_max_size netif_set_gso_max_size #if LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) #if LINUX_VERSION_CODE < KERNEL_VERSION(5,12,0) #define PHY_MAC_INTERRUPT PHY_IGNORE_INTERRUPT @@ -613,6 +617,7 @@ memcpy(dev->dev_addr, addr, 6); } #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,19,0) */ #ifndef FALSE #define TRUE 1 diff --git a/src/r8152.c b/src/r8152.c index 9c2bd16..5d6df58 100644 --- a/src/r8152.c +++ b/src/r8152.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021 Realtek Semiconductor Corp. All rights reserved. + * Copyright (c) 2023 Realtek Semiconductor Corp. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -32,7 +32,7 @@ #include "compatibility.h" /* Version Information */ -#define DRIVER_VERSION "v2.16.3 (2022/07/06)" +#define DRIVER_VERSION "v2.17.1 (2023/06/13)" #define DRIVER_AUTHOR "Realtek nic sw " #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" #define MODULENAME "r8152" @@ -140,9 +140,12 @@ #define USB_DEV_STAT 0xb808 #define USB_CONNECT_TIMER 0xcbf8 #define USB_MSC_TIMER 0xcbfc +#define USB_OUTER_FW_VER 0xcd54 #define USB_BURST_SIZE 0xcfc0 #define USB_FW_FIX_EN0 0xcfca #define USB_FW_FIX_EN1 0xcfcc +#define USB_FW_PLA_VER 0xcfd6 +#define USB_FW_USB_VER 0xcfd7 #define USB_LPM_CONFIG 0xcfd8 #define USB_EFUSE 0xcfdb #define USB_ECM_OPTION 0xcfee @@ -153,6 +156,7 @@ #define USB_SPEED_OPTION 0xd32a #define USB_FW_CTRL 0xd334 /* RTL8153B */ #define USB_FC_TIMER 0xd340 +#define USB_OUTSIDE_FW_VER 0xd3cc #define USB_USB_CTRL 0xd406 #define USB_PHY_CTRL 0xd408 #define USB_TX_AGG 0xd40a @@ -211,6 +215,7 @@ #define OCP_EEE_AR 0xa41a #define OCP_EEE_DATA 0xa41c #define OCP_PHY_STATUS 0xa420 +#define OCP_INTR_EN 0xa424 #define OCP_NCTL_CFG 0xa42c #define OCP_POWER_CFG 0xa430 #define OCP_EEE_CFG 0xa432 @@ -643,6 +648,9 @@ enum spd_duplex { #define PHY_STAT_LAN_ON 3 #define PHY_STAT_PWRDN 5 +/* OCP_INTR_EN */ +#define INTR_SPEED_FORCE BIT(3) + /* OCP_NCTL_CFG */ #define PGA_RETURN_EN BIT(1) @@ -811,6 +819,13 @@ enum rtl8152_flags { #define MCU_TYPE_PLA 0x0100 #define MCU_TYPE_USB 0x0000 +#define DEVICE_ID_LENOVO_USB_C_TRAVEL_HUB 0x721e +#define DEVICE_ID_THINKPAD_ONELINK_PLUS_DOCK 0x3054 +#define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2 0x3082 +#define DEVICE_ID_THINKPAD_USB_C_DONGLE 0x720c +#define DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2 0xa387 +#define DEVICE_ID_THINKPAD_USB_C_DOCK_GEN3 0x3062 + struct tally_counter { __le64 tx_packets; __le64 rx_packets; @@ -970,6 +985,7 @@ struct r8152 { u32 rx_copybreak; u32 rx_pending; u32 fc_pause_on, fc_pause_off; + u32 rx_agg_free_ref; unsigned int pipe_in, pipe_out, pipe_intr, pipe_ctrl_in, pipe_ctrl_out; @@ -1054,11 +1070,8 @@ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) kfree(tmp); - if (ret < 0) { - if (ret == -ETIMEDOUT) - usb_queue_reset_device(tp->intf); + if (ret < 0) netif_err(tp, drv, tp->netdev, "get_registers %d\n", ret); - } return ret; } @@ -1079,11 +1092,8 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) kfree(tmp); - if (ret < 0) { - if (ret == -ETIMEDOUT) - usb_queue_reset_device(tp->intf); + if (ret < 0) netif_err(tp, drv, tp->netdev, "set_registers %d\n", ret); - } return ret; } @@ -1160,16 +1170,24 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, byteen_end = byteen & BYTE_EN_END_MASK; byen = byteen_start | (byteen_start << 4); - ret = set_registers(tp, index, type | byen, 4, data); - if (ret < 0) - goto error1; - index += 4; - data += 4; - size -= 4; + /* Split the first DWORD if the byte_en is not 0xff */ + if (byen != BYTE_EN_DWORD) { + ret = set_registers(tp, index, type | byen, 4, data); + if (ret < 0) + goto error1; + + index += 4; + data += 4; + size -= 4; + } if (size) { - size -= 4; + byen = byteen_end | (byteen_end >> 4); + + /* Split the last DWORD if the byte_en is not 0xff */ + if (byen != BYTE_EN_DWORD) + size -= 4; while (size) { if (size > limit) { @@ -1196,10 +1214,9 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, u16 byteen, } } - byen = byteen_end | (byteen_end >> 4); - ret = set_registers(tp, index, type | byen, 4, data); - if (ret < 0) - goto error1; + /* Set the last DWORD */ + if (byen != BYTE_EN_DWORD) + ret = set_registers(tp, index, type | byen, 4, data); } error1: @@ -1499,7 +1516,7 @@ static int rtl_mapt_read(struct r8152 *tp, char *mac_obj_name, } ret = hex2bin(buf, obj->string.pointer + 9, sizeof(buf)); - if (ret < 0 || !is_valid_ether_addr(buf)) { + if (!(ret == 0 && is_valid_ether_addr(buf))) { netif_warn(tp, probe, tp->netdev, "Invalid MAC for pass-thru MAC addr: %d, %pM\n", ret, buf); @@ -1835,7 +1852,9 @@ static void intr_callback(struct urb *urb) "Stop submitting intr, status %d\n", status); return; case -EOVERFLOW: - netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n"); + if (net_ratelimit()) + netif_info(tp, intr, tp->netdev, + "intr status -EOVERFLOW\n"); goto resubmit; /* -EPIPE: should clear the halt */ default: @@ -1901,7 +1920,7 @@ static struct rx_agg *alloc_rx_agg(struct r8152 *tp, gfp_t mflags) if (!rx_agg) return NULL; - rx_agg->page = alloc_pages(mflags | __GFP_COMP, order); + rx_agg->page = alloc_pages(mflags | __GFP_COMP | __GFP_NOWARN, order); if (!rx_agg->page) goto free_rx; @@ -2166,7 +2185,7 @@ static inline void rtl_rx_vlan_tag(struct rx_desc *desc, struct sk_buff *skb) #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) */ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, - struct sk_buff *skb, u32 len, u32 transport_offset) + struct sk_buff *skb, u32 len) { u32 mss = skb_shinfo(skb)->gso_size; u32 opts1, opts2 = 0; @@ -2177,6 +2196,8 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, opts1 = len | TX_FS | TX_LS; if (mss) { + u32 transport_offset = (u32)skb_transport_offset(skb); + if (transport_offset > GTTCPHO_MAX) { netif_warn(tp, tx_err, tp->netdev, "Invalid transport offset 0x%x for TSO\n", @@ -2207,6 +2228,7 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, opts1 |= transport_offset << GTTCPHO_SHIFT; opts2 |= min(mss, MSS_MAX) << MSS_SHIFT; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + u32 transport_offset = (u32)skb_transport_offset(skb); u8 ip_protocol; if (transport_offset > TCPHO_MAX) { @@ -2270,7 +2292,6 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) struct tx_desc *tx_desc; struct sk_buff *skb; unsigned int len; - u32 offset; skb = __skb_dequeue(&skb_head); if (!skb) @@ -2286,9 +2307,7 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) tx_data = tx_agg_align(tx_data); tx_desc = (struct tx_desc *)tx_data; - offset = (u32)skb_transport_offset(skb); - - if (r8152_tx_csum(tp, tx_desc, skb, skb->len, offset)) { + if (r8152_tx_csum(tp, tx_desc, skb, skb->len)) { r8152_csum_workaround(tp, skb, &skb_head); continue; } @@ -2373,7 +2392,6 @@ static int r8152_tx_agg_sg_fill(struct r8152 *tp, struct tx_agg *agg) struct sk_buff *skb; int num_sgs, headroom; unsigned int len; - u32 offset; skb = __skb_dequeue(&skb_head); if (!skb) @@ -2408,9 +2426,7 @@ static int r8152_tx_agg_sg_fill(struct r8152 *tp, struct tx_agg *agg) break; } - offset = (u32)skb_transport_offset(skb); - - if (r8152_tx_csum(tp, &tx_desc, skb, len, offset)) { + if (r8152_tx_csum(tp, &tx_desc, skb, len)) { r8152_csum_workaround(tp, skb, &skb_head); continue; } @@ -2546,7 +2562,9 @@ static struct rx_agg *rtl_get_free_rx(struct r8152 *tp, gfp_t mflags) agg_free = agg; continue; } - if (rx_count_exceed(tp)) { + if (tp->rx_agg_free_ref) { + tp->rx_agg_free_ref--; + } else if (rx_count_exceed(tp)) { list_del_init(&agg->list); free_rx_agg(tp, agg); } @@ -2556,8 +2574,10 @@ static struct rx_agg *rtl_get_free_rx(struct r8152 *tp, gfp_t mflags) spin_unlock_irqrestore(&tp->rx_lock, flags); - if (!agg_free && atomic_read(&tp->rx_count) < tp->rx_pending) + if (!agg_free && atomic_read(&tp->rx_count) < tp->rx_pending) { agg_free = alloc_rx_agg(tp, mflags); + tp->rx_agg_free_ref += RTL8152_MAX_RX; + } return agg_free; } @@ -2977,8 +2997,9 @@ static void rtl8152_set_rx_mode(struct net_device *netdev) ocp_data |= RCR_AM | RCR_AAP; mc_filter[1] = 0xffffffff; mc_filter[0] = 0xffffffff; - } else if ((netdev_mc_count(netdev) > multicast_filter_limit) || - (netdev->flags & IFF_ALLMULTI)) { + } else if ((netdev->flags & IFF_MULTICAST && + netdev_mc_count(netdev) > multicast_filter_limit) || + (netdev->flags & IFF_ALLMULTI)) { /* Too many to filter perfectly -- accept all multicasts. */ ocp_data |= RCR_AM; mc_filter[1] = 0xffffffff; @@ -2999,15 +3020,18 @@ static void rtl8152_set_rx_mode(struct net_device *netdev) ocp_data |= RCR_AM; } #else - struct netdev_hw_addr *ha; - mc_filter[1] = 0; mc_filter[0] = 0; - netdev_for_each_mc_addr(ha, netdev) { - int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; - mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); - ocp_data |= RCR_AM; + if (netdev->flags & IFF_MULTICAST) { + struct netdev_hw_addr *ha; + + netdev_for_each_mc_addr(ha, netdev) { + int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; + + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); + ocp_data |= RCR_AM; + } } #endif } @@ -3040,9 +3064,9 @@ rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, { u32 mss = skb_shinfo(skb)->gso_size; int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX; - int offset = skb_transport_offset(skb); - if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset) + if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && + skb_transport_offset(skb) > max_offset) features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); else if (!rtl_gso_check(dev, skb)) features &= ~NETIF_F_GSO_MASK; @@ -3327,12 +3351,16 @@ static int rtl_enable(struct r8152 *tp) ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data); switch (tp->version) { - case RTL_VER_08: - case RTL_VER_09: - case RTL_VER_14: - r8153b_rx_agg_chg_indicate(tp); + case RTL_VER_01: + case RTL_VER_02: + case RTL_VER_03: + case RTL_VER_04: + case RTL_VER_05: + case RTL_VER_06: + case RTL_VER_07: break; default: + r8153b_rx_agg_chg_indicate(tp); break; } @@ -3386,7 +3414,6 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp) 640 / 8); ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EXTRA_AGGR_TMR, ocp_data); - r8153b_rx_agg_chg_indicate(tp); break; default: @@ -3420,7 +3447,6 @@ static void r8153_set_rx_early_size(struct r8152 *tp) case RTL_VER_15: ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE, ocp_data / 8); - r8153b_rx_agg_chg_indicate(tp); break; default: WARN_ON_ONCE(1); @@ -3443,7 +3469,6 @@ static int rtl8153_enable(struct r8152 *tp) rtl_set_ifg(tp, rtl8152_get_speed(tp)); switch (tp->version) { - case RTL_VER_09: case RTL_VER_14: ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); ocp_data &= ~FC_PATCH_TASK; @@ -3757,6 +3782,15 @@ static void r8153_u2p3en(struct r8152 *tp, bool enable) ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data); } +static bool r8156b_flash_used(struct r8152 *tp) +{ + if ((ocp_read_word(tp, MCU_TYPE_PLA, PLA_GPHY_CTRL) & GPHY_FLASH) && + !(ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & BYPASS_FLASH)) + return true; + else + return false; +} + static void r8153b_ups_flags(struct r8152 *tp) { u32 ups_flags = 0; @@ -4056,11 +4090,12 @@ static void r8153c_ups_en(struct r8152 *tp, bool enable) static void r8156_ups_en(struct r8152 *tp, bool enable) { - u32 ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); - if (enable) { + u32 ocp_data; + r8156_ups_flags(tp); + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); ocp_data |= UPS_EN | USP_PREWAKE | PHASE2_EN; ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); @@ -4074,11 +4109,22 @@ static void r8156_ups_en(struct r8152 *tp, bool enable) ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPHY_XTAL); ocp_data &= ~OOBS_POLLING; ocp_write_byte(tp, MCU_TYPE_USB, USB_UPHY_XTAL, ocp_data); + + if (r8156b_flash_used(tp)) { + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, + USB_GPHY_CTRL); + ocp_data &= ~GPHY_PATCH_DONE; + ocp_write_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL, + ocp_data); + } break; default: break; } } else { + u32 ocp_data; + + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_POWER_CUT); ocp_data &= ~(UPS_EN | USP_PREWAKE); ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data); @@ -4091,6 +4137,23 @@ static void r8156_ups_en(struct r8152 *tp, bool enable) rtl8152_set_speed(tp, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + } else { + switch (tp->version) { + case RTL_VER_13: + case RTL_VER_15: + if (r8156b_flash_used(tp)) { + ocp_data = ocp_read_word(tp, + MCU_TYPE_USB, + USB_GPHY_CTRL); + ocp_data |= GPHY_PATCH_DONE; + ocp_write_word(tp, MCU_TYPE_USB, + USB_GPHY_CTRL, + ocp_data); + } + break; + default: + break; + } } } } @@ -4337,29 +4400,10 @@ static void rtl_reset_bmu(struct r8152 *tp) /* Clear the bp to stop the firmware before loading a new one */ static void rtl_clear_bp(struct r8152 *tp, u16 type) { - switch (tp->version) { - case RTL_VER_01: - case RTL_VER_02: - case RTL_VER_07: - break; - case RTL_VER_03: - case RTL_VER_04: - case RTL_VER_05: - case RTL_VER_06: - ocp_write_byte(tp, type, PLA_BP_EN, 0); - break; - case RTL_VER_14: - ocp_write_word(tp, type, USB_BP2_EN, 0); + u16 bp[16] = {0}; + u16 bp_num; - ocp_write_word(tp, type, USB_BP_8, 0); - ocp_write_word(tp, type, USB_BP_9, 0); - ocp_write_word(tp, type, USB_BP_10, 0); - ocp_write_word(tp, type, USB_BP_11, 0); - ocp_write_word(tp, type, USB_BP_12, 0); - ocp_write_word(tp, type, USB_BP_13, 0); - ocp_write_word(tp, type, USB_BP_14, 0); - ocp_write_word(tp, type, USB_BP_15, 0); - break; + switch (tp->version) { case RTL_VER_08: case RTL_VER_09: case RTL_VER_10: @@ -4367,38 +4411,45 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type) case RTL_VER_12: case RTL_VER_13: case RTL_VER_15: - default: if (type == MCU_TYPE_USB) { ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0); - - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0); - } else { - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0); + bp_num = 16; + break; } + fallthrough; + case RTL_VER_03: + case RTL_VER_04: + case RTL_VER_05: + case RTL_VER_06: + ocp_write_byte(tp, type, PLA_BP_EN, 0); + fallthrough; + case RTL_VER_01: + case RTL_VER_02: + case RTL_VER_07: + bp_num = 8; + break; + case RTL_VER_14: + default: + ocp_write_word(tp, type, USB_BP2_EN, 0); + bp_num = 16; break; } - ocp_write_word(tp, type, PLA_BP_0, 0); - ocp_write_word(tp, type, PLA_BP_1, 0); - ocp_write_word(tp, type, PLA_BP_2, 0); - ocp_write_word(tp, type, PLA_BP_3, 0); - ocp_write_word(tp, type, PLA_BP_4, 0); - ocp_write_word(tp, type, PLA_BP_5, 0); - ocp_write_word(tp, type, PLA_BP_6, 0); - ocp_write_word(tp, type, PLA_BP_7, 0); + generic_ocp_write(tp, PLA_BP_0, BYTE_EN_DWORD, bp_num << 1, bp, type); /* wait 3 ms to make sure the firmware is stopped */ usleep_range(3000, 6000); ocp_write_word(tp, type, PLA_BP_BA, 0); } +static bool rtl_check_fw_ver_ok(struct r8152 *tp, u16 index, u8 new_ver) +{ + if (!index || new_ver > ocp_read_byte(tp, MCU_TYPE_USB, index)) + return true; + else + return false; +} + static inline void rtl_reset_ocp_base(struct r8152 *tp) { tp->ocp_base = -1; @@ -5069,14 +5120,10 @@ static void r8152b_firmware(struct r8152 *tp) 0x00, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static u8 usb_patch_a2[] = { - 0x10, 0xe0, 0x2d, 0xe0, - 0x0e, 0xe0, 0x0d, 0xe0, - 0x0c, 0xe0, 0x0b, 0xe0, - 0x0a, 0xe0, 0x09, 0xe0, - 0x08, 0xe0, 0x07, 0xe0, - 0x06, 0xe0, 0x05, 0xe0, - 0x04, 0xe0, 0x03, 0xe0, - 0x02, 0xe0, 0x01, 0xe0, + 0x08, 0xe0, 0x25, 0xe0, + 0x8e, 0xe0, 0xb8, 0xe0, + 0xba, 0xe0, 0xbc, 0xe0, + 0xbe, 0xe0, 0xc0, 0xe0, 0x1c, 0xc2, 0x40, 0x71, 0x9f, 0x48, 0x40, 0x99, 0x1f, 0x48, 0x40, 0x99, @@ -5092,7 +5139,7 @@ static void r8152b_firmware(struct r8152 *tp) 0x00, 0xb8, 0xc2, 0x09, 0x28, 0xd4, 0xd4, 0xc4, 0x06, 0xd4, 0x00, 0xb0, - 0x61, 0xc7, 0x5a, 0xc6, + 0x69, 0xc7, 0x62, 0xc6, 0xe4, 0x9e, 0x0f, 0x1e, 0xe6, 0x8e, 0xe6, 0x76, 0xef, 0x49, 0xfe, 0xf1, @@ -5101,46 +5148,79 @@ static void r8152b_firmware(struct r8152 *tp) 0xb8, 0x25, 0x48, 0x23, 0x68, 0x27, 0x04, 0xb4, 0x05, 0xb4, 0x06, 0xb4, - 0x4a, 0xc6, 0xe3, 0x23, + 0x52, 0xc6, 0xe3, 0x23, 0xfe, 0x39, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x13, - 0x0a, 0xf0, 0xb0, 0x49, + 0x0c, 0xf0, 0xb0, 0x49, 0x04, 0xf1, 0x01, 0x05, 0xb1, 0x25, 0xfa, 0xe7, 0xb8, 0x33, 0x35, 0x43, - 0x30, 0x31, 0xf6, 0xe7, + 0x26, 0x31, 0x01, 0x05, + 0xb1, 0x25, 0xf4, 0xe7, 0x06, 0xb0, 0x05, 0xb0, 0xae, 0x41, 0x25, 0x31, - 0x37, 0xc5, 0x6c, 0x41, + 0x3d, 0xc5, 0x6c, 0x41, 0x04, 0xb0, 0x48, 0x26, - 0x05, 0xb4, 0x36, 0xc7, - 0x2f, 0xc6, 0x04, 0x06, + 0x05, 0xb4, 0x3c, 0xc7, + 0x35, 0xc6, 0x04, 0x06, 0xe4, 0x9e, 0x0f, 0x1e, 0xe6, 0x8e, 0xe6, 0x76, 0xef, 0x49, 0xfe, 0xf1, 0xe0, 0x76, 0xe8, 0x25, 0xe8, 0x23, 0xf8, 0x27, - 0x24, 0xc5, 0x6c, 0x41, + 0x2a, 0xc5, 0x6c, 0x41, 0x33, 0x22, 0x23, 0x39, 0x7c, 0x41, 0xfd, 0x31, - 0x1f, 0xc6, 0x7e, 0x41, - 0x20, 0xc6, 0xc4, 0x9f, + 0x25, 0xc6, 0x7e, 0x41, 0xf2, 0x21, 0xdf, 0x30, 0xdf, 0x30, 0x05, 0xb0, - 0xc2, 0x9d, 0x53, 0x22, - 0x25, 0x31, 0xa3, 0x31, - 0x12, 0xc7, 0xb7, 0x31, - 0x12, 0xc7, 0x77, 0x41, - 0x12, 0xc7, 0xe6, 0x9e, - 0x0f, 0xc3, 0xde, 0x30, - 0x60, 0x64, 0xe8, 0x8c, + 0x53, 0x22, 0x25, 0x31, + 0xa3, 0x31, 0x1b, 0xc7, + 0xb7, 0x31, 0x1b, 0xc7, + 0x77, 0x41, 0x1b, 0xc7, + 0x1b, 0xc4, 0x84, 0x9f, + 0x80, 0x9e, 0x16, 0xc3, + 0xde, 0x30, 0x60, 0x65, + 0x82, 0x9d, 0x8f, 0x1e, + 0x8f, 0x1e, 0x8f, 0x1e, + 0x86, 0x8e, 0x86, 0x76, + 0xef, 0x49, 0xfe, 0xf1, 0x06, 0xc7, 0x04, 0x1e, 0xe0, 0x8e, 0x02, 0xc4, 0x00, 0xbc, 0xb6, 0x02, 0x34, 0xe4, 0x00, 0xc0, 0x25, 0x00, 0xff, 0x00, 0x7f, 0x00, 0x00, 0xf8, - 0xf0, 0xc4, 0x08, 0xdc }; + 0x88, 0xd3, 0x08, 0xdc, + 0x1f, 0xc0, 0x1f, 0xc1, + 0x00, 0x1c, 0x00, 0x99, + 0x1d, 0xc1, 0x02, 0x99, + 0x1c, 0xc1, 0x04, 0x99, + 0x06, 0x9c, 0x1a, 0xc1, + 0x08, 0x99, 0x0a, 0x9c, + 0x18, 0xc1, 0x0c, 0x99, + 0x17, 0xc1, 0x0e, 0x99, + 0x10, 0x9c, 0x15, 0xc1, + 0x12, 0x99, 0x14, 0xc1, + 0x14, 0x99, 0x13, 0xc1, + 0x16, 0x99, 0x12, 0xc1, + 0x18, 0x99, 0x08, 0xc1, + 0x1a, 0x9c, 0x0f, 0xc4, + 0x02, 0xc0, 0x00, 0xb8, + 0x04, 0x33, 0x10, 0xc3, + 0x02, 0x00, 0x08, 0x00, + 0x38, 0x00, 0x48, 0x00, + 0x08, 0x00, 0x40, 0x00, + 0x00, 0x03, 0x80, 0x01, + 0x12, 0x7a, 0x01, 0x01, + 0xe0, 0xcb, 0x02, 0xc0, + 0x00, 0xb8, 0x3a, 0x4e, + 0x02, 0xc0, 0x00, 0xb8, + 0x3a, 0x4e, 0x02, 0xc0, + 0x00, 0xb8, 0x3a, 0x4e, + 0x02, 0xc0, 0x00, 0xb8, + 0x3a, 0x4e, 0x02, 0xc0, + 0x00, 0xb8, 0x3a, 0x4e }; u32 ocp_data; rtl_clear_bp(tp, MCU_TYPE_PLA); @@ -5164,7 +5244,7 @@ static void r8152b_firmware(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_USB, 0xfc28, 0x0c87); ocp_write_word(tp, MCU_TYPE_USB, 0xfc2a, 0x024f); - ocp_write_word(tp, MCU_TYPE_USB, 0xfc2c, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, 0xfc2c, 0x3303); ocp_write_word(tp, MCU_TYPE_USB, 0xfc2e, 0x0000); ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd428); @@ -5179,6 +5259,10 @@ static void r8152b_firmware(struct r8152 *tp) ocp_data &= ~BIT(0); ocp_write_word(tp, MCU_TYPE_USB, 0xc4d6, ocp_data); + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xc5d4); + ocp_data |= BIT(2) | BIT(5); + ocp_write_word(tp, MCU_TYPE_USB, 0xc5d4, ocp_data); + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, 0xd428); ocp_data &= ~BIT(15); ocp_write_word(tp, MCU_TYPE_USB, 0xd428, ocp_data); @@ -5389,12 +5473,12 @@ static void wait_oob_link_list_ready(struct r8152 *tp) static void r8156b_wait_loading_flash(struct r8152 *tp) { - if ((ocp_read_word(tp, MCU_TYPE_PLA, PLA_GPHY_CTRL) & GPHY_FLASH) && - !(ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & BYPASS_FLASH)) { + if (r8156b_flash_used(tp)) { int i; for (i = 0; i < 100; i++) { - if (ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & GPHY_PATCH_DONE) + if (ocp_read_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL) & + GPHY_PATCH_DONE) break; usleep_range(1000, 2000); } @@ -5558,7 +5642,6 @@ static void r8153_wdt1_end(struct r8152 *tp) #define DBG_COUNTER_MASK 0x1f #define DBG_DRV_RUNNING (1 << 5) -#define DBG_IS_LINUX 8 #define DGB_DRV_STATE_MASK (3 << 14) #define DGB_DRV_STATE_LOAD (2 << 14) #define DGB_DRV_STATE_UNLOAD (1 << 14) @@ -5567,9 +5650,10 @@ static void rtl_set_dbg_info_init(struct r8152 *tp) u32 counter; counter = ocp_read_byte(tp, MCU_TYPE_USB, 0xcfcf); - counter = (counter & DBG_COUNTER_MASK) + 1; + counter++; + counter &= DBG_COUNTER_MASK; ocp_write_byte(tp, MCU_TYPE_USB, 0xcfcf, counter | DBG_DRV_RUNNING); - counter = (counter << 5) | DBG_IS_LINUX; + counter = (counter << 5) | 0xb; ocp_write_word(tp, MCU_TYPE_USB, 0xcfd0, counter); } @@ -5582,6 +5666,38 @@ static void rtl_set_dbg_info_state(struct r8152 *tp, u16 state) ocp_write_word(tp, MCU_TYPE_USB, 0xcfd0, state | ocp_data); } +static void rtl_fw_ver_erase(struct r8152 *tp) +{ + u16 outer_ver; + + switch (tp->version) { + case RTL_VER_01: + case RTL_VER_02: + case RTL_VER_03: + case RTL_VER_04: + case RTL_VER_05: + case RTL_VER_06: + case RTL_VER_07: + case RTL_TEST_01: + return; + case RTL_VER_10: + case RTL_VER_11: + case RTL_VER_12: + case RTL_VER_13: + case RTL_VER_15: + outer_ver = USB_OUTSIDE_FW_VER; + break; + default: + outer_ver = USB_OUTER_FW_VER; + break; + } + + if (!ocp_read_word(tp, MCU_TYPE_USB, outer_ver)) { + ocp_write_word(tp, MCU_TYPE_USB, outer_ver, 0); + ocp_write_word(tp, MCU_TYPE_USB, USB_FW_PLA_VER, 0); + } +} + static void r8153_firmware(struct r8152 *tp) { if (tp->version == RTL_VER_03) { @@ -6600,44 +6716,77 @@ static void r8153b_firmware(struct r8152 *tp) if (tp->version == RTL_VER_09) { u32 ocp_data; static u8 usb_patch2_b[] = { - 0x10, 0xe0, 0x26, 0xe0, - 0x3a, 0xe0, 0x58, 0xe0, - 0x6c, 0xe0, 0x85, 0xe0, - 0xa5, 0xe0, 0xbe, 0xe0, - 0xd8, 0xe0, 0xdb, 0xe0, - 0xf3, 0xe0, 0x05, 0xe1, - 0x0d, 0xe1, 0x6b, 0xe1, - 0x71, 0xe1, 0x92, 0xe1, - 0x16, 0xc0, 0x00, 0x75, - 0xd1, 0x49, 0x0d, 0xf0, - 0x0f, 0xc0, 0x0f, 0xc5, - 0x00, 0x1e, 0x08, 0x9e, - 0x0c, 0x9d, 0x0c, 0xc6, - 0x0a, 0x9e, 0x8f, 0x1c, - 0x0e, 0x8c, 0x0e, 0x74, - 0xcf, 0x49, 0xfe, 0xf1, - 0x02, 0xc0, 0x00, 0xb8, - 0x96, 0x31, 0x00, 0xdc, - 0x24, 0xe4, 0x80, 0x02, - 0x34, 0xd3, 0xff, 0xc3, - 0x60, 0x72, 0xa1, 0x49, - 0x0d, 0xf0, 0xf8, 0xc3, - 0xf8, 0xc2, 0x00, 0x1c, - 0x68, 0x9c, 0xf6, 0xc4, - 0x6a, 0x9c, 0x6c, 0x9a, - 0x8f, 0x1c, 0x6e, 0x8c, - 0x6e, 0x74, 0xcf, 0x49, - 0xfe, 0xf1, 0x04, 0xc0, - 0x02, 0xc2, 0x00, 0xba, - 0xa8, 0x28, 0xf8, 0xc7, - 0xea, 0xc0, 0x00, 0x75, + 0x10, 0xe0, 0x5b, 0xe0, + 0x7c, 0xe0, 0x9c, 0xe0, + 0xb0, 0xe0, 0xc9, 0xe0, + 0xea, 0xe0, 0x46, 0xe1, + 0x62, 0xe1, 0x65, 0xe1, + 0x7d, 0xe1, 0x8f, 0xe1, + 0x97, 0xe1, 0xf5, 0xe1, + 0x11, 0xe2, 0x22, 0xe2, + 0x43, 0xc4, 0x80, 0x63, + 0xb2, 0x49, 0x05, 0xf0, + 0x41, 0xc4, 0x02, 0xc3, + 0x00, 0xbb, 0x88, 0x3d, + 0x64, 0xc4, 0x3b, 0xc3, + 0x84, 0x9b, 0x00, 0x1b, + 0x86, 0x8b, 0x86, 0x73, + 0xbf, 0x49, 0xfe, 0xf1, + 0x80, 0x73, 0x35, 0xc2, + 0x40, 0x9b, 0x34, 0xc3, + 0x80, 0x9b, 0x83, 0x1b, + 0x86, 0x8b, 0x86, 0x73, + 0xbf, 0x49, 0xfe, 0xf1, + 0x2e, 0xc3, 0x84, 0x9b, + 0x00, 0x1b, 0x86, 0x8b, + 0x86, 0x73, 0xbf, 0x49, + 0xfe, 0xf1, 0x80, 0x73, + 0xba, 0x48, 0xbb, 0x48, + 0x80, 0x9b, 0x83, 0x1b, + 0x86, 0x8b, 0x86, 0x73, + 0xbf, 0x49, 0xfe, 0xf1, + 0x20, 0xc3, 0x84, 0x9b, + 0x1f, 0xc3, 0x80, 0x9b, + 0x83, 0x1b, 0x86, 0x8b, + 0x86, 0x73, 0xbf, 0x49, + 0xfe, 0xf1, 0x11, 0xc3, + 0x84, 0x9b, 0x40, 0x73, + 0x80, 0x9b, 0x83, 0x1b, + 0x86, 0x8b, 0x86, 0x73, + 0xbf, 0x49, 0xfe, 0xf1, + 0x0d, 0xc4, 0x80, 0x73, + 0xbb, 0x48, 0x80, 0x9b, + 0x02, 0xc3, 0x00, 0xbb, + 0x06, 0x3e, 0xee, 0xcf, + 0x6c, 0xe8, 0xe0, 0xcb, + 0x2e, 0xc3, 0x00, 0xa0, + 0x08, 0xb4, 0x4a, 0xd8, + 0x00, 0xb4, 0x00, 0x92, + 0x1c, 0xc6, 0xc0, 0x61, + 0x04, 0x11, 0x15, 0xf1, + 0x19, 0xc6, 0xc0, 0x61, + 0x9c, 0x20, 0x9c, 0x24, + 0x09, 0x11, 0x0f, 0xf1, + 0x14, 0xc6, 0x01, 0x19, + 0xc0, 0x89, 0x13, 0xc1, + 0x13, 0xc6, 0x24, 0x9e, + 0x00, 0x1e, 0x26, 0x8e, + 0x26, 0x76, 0xef, 0x49, + 0xfe, 0xf1, 0x22, 0x76, + 0x08, 0xc1, 0x22, 0x9e, + 0x07, 0xc6, 0x02, 0xc1, + 0x00, 0xb9, 0x8c, 0x08, + 0x18, 0xb4, 0x4a, 0xb4, + 0x90, 0xcc, 0x80, 0xd4, + 0x08, 0xdc, 0x10, 0xe8, + 0x1f, 0xc0, 0x00, 0x75, 0xd1, 0x49, 0x15, 0xf0, 0x19, 0xc7, 0x17, 0xc2, 0xec, 0x9a, 0x00, 0x19, 0xee, 0x89, 0xee, 0x71, 0x9f, 0x49, 0xfe, 0xf1, 0xea, 0x71, 0x9f, 0x49, - 0x0a, 0xf0, 0xd9, 0xc2, + 0x0a, 0xf0, 0x11, 0xc2, 0xec, 0x9a, 0x00, 0x19, 0xe8, 0x99, 0x81, 0x19, 0xee, 0x89, 0xee, 0x71, @@ -6645,20 +6794,21 @@ static void r8153b_firmware(struct r8152 *tp) 0x06, 0xc3, 0x02, 0xc2, 0x00, 0xba, 0xf0, 0x1d, 0x4c, 0xe8, 0x00, 0xdc, - 0x00, 0xd4, 0xcb, 0xc0, + 0x00, 0xd4, 0x34, 0xd3, + 0x24, 0xe4, 0x7b, 0xc0, 0x00, 0x75, 0xd1, 0x49, - 0x0d, 0xf0, 0xc4, 0xc0, - 0xc4, 0xc5, 0x00, 0x1e, - 0x08, 0x9e, 0xc2, 0xc6, + 0x0d, 0xf0, 0x74, 0xc0, + 0x74, 0xc5, 0x00, 0x1e, + 0x08, 0x9e, 0x72, 0xc6, 0x0a, 0x9e, 0x0c, 0x9d, 0x8f, 0x1c, 0x0e, 0x8c, 0x0e, 0x74, 0xcf, 0x49, 0xfe, 0xf1, 0x04, 0xc0, 0x02, 0xc1, 0x00, 0xb9, 0xc4, 0x16, 0x20, 0xd4, - 0xb6, 0xc0, 0x00, 0x75, + 0x66, 0xc0, 0x00, 0x75, 0xd1, 0x48, 0x00, 0x9d, - 0xe5, 0xc7, 0xaf, 0xc2, + 0xe3, 0xc7, 0x5f, 0xc2, 0xec, 0x9a, 0x00, 0x19, 0xe8, 0x9a, 0x81, 0x19, 0xee, 0x89, 0xee, 0x71, @@ -6672,46 +6822,81 @@ static void r8153b_firmware(struct r8152 *tp) 0xc0, 0x88, 0x1e, 0xc6, 0xc0, 0x70, 0x8f, 0x49, 0x0e, 0xf0, 0x8f, 0x48, - 0x93, 0xc6, 0xca, 0x98, + 0x1b, 0xc6, 0xca, 0x98, 0x11, 0x18, 0xc8, 0x98, 0x16, 0xc0, 0xcc, 0x98, 0x8f, 0x18, 0xce, 0x88, 0xce, 0x70, 0x8f, 0x49, 0xfe, 0xf1, 0x0b, 0xe0, - 0x43, 0xc6, 0x00, 0x18, + 0x36, 0xc6, 0x00, 0x18, 0xc8, 0x98, 0x0b, 0xc0, 0xcc, 0x98, 0x81, 0x18, 0xce, 0x88, 0xce, 0x70, 0x8f, 0x49, 0xfe, 0xf1, 0x02, 0xc0, 0x00, 0xb8, 0xf2, 0x19, 0x40, 0xd3, - 0x20, 0xe4, 0x33, 0xc2, - 0x40, 0x71, 0x91, 0x48, - 0x40, 0x99, 0x30, 0xc2, - 0x00, 0x19, 0x48, 0x99, - 0xf8, 0xc1, 0x4c, 0x99, - 0x81, 0x19, 0x4e, 0x89, - 0x4e, 0x71, 0x9f, 0x49, - 0xfe, 0xf1, 0x0b, 0xc1, - 0x4c, 0x99, 0x81, 0x19, - 0x4e, 0x89, 0x4e, 0x71, - 0x9f, 0x49, 0xfe, 0xf1, - 0x02, 0x71, 0x02, 0xc2, - 0x00, 0xba, 0x0e, 0x34, - 0x24, 0xe4, 0x19, 0xc2, - 0x40, 0x71, 0x91, 0x48, - 0x40, 0x99, 0x16, 0xc2, - 0x00, 0x19, 0x48, 0x99, - 0xde, 0xc1, 0x4c, 0x99, - 0x81, 0x19, 0x4e, 0x89, - 0x4e, 0x71, 0x9f, 0x49, - 0xfe, 0xf1, 0xf1, 0xc1, - 0x4c, 0x99, 0x81, 0x19, - 0x4e, 0x89, 0x4e, 0x71, - 0x9f, 0x49, 0xfe, 0xf1, - 0x02, 0x71, 0x02, 0xc2, - 0x00, 0xba, 0x60, 0x33, - 0x34, 0xd3, 0x00, 0xdc, + 0x20, 0xe4, 0x00, 0xdc, + 0x90, 0x49, 0x1f, 0xf0, + 0x29, 0xc0, 0x01, 0x66, + 0x05, 0x16, 0x3f, 0xf0, + 0x25, 0x16, 0x45, 0xf0, + 0x09, 0x16, 0x23, 0xf0, + 0x16, 0xe0, 0x1a, 0xc2, + 0x40, 0x76, 0xe1, 0x48, + 0x40, 0x9e, 0x17, 0xc2, + 0x00, 0x1e, 0x48, 0x9e, + 0xec, 0xc6, 0x4c, 0x9e, + 0x81, 0x1e, 0x4e, 0x8e, + 0x4e, 0x76, 0xef, 0x49, + 0xfe, 0xf1, 0x0b, 0xc6, + 0x4c, 0x9e, 0x81, 0x1e, + 0x4e, 0x8e, 0x4e, 0x76, + 0xef, 0x49, 0xfe, 0xf1, + 0x90, 0x49, 0x02, 0xc7, + 0x00, 0xbf, 0xe2, 0x27, + 0x24, 0xe4, 0x34, 0xd3, + 0x00, 0xdc, 0x00, 0xdc, + 0x24, 0xe4, 0x80, 0x02, + 0x34, 0xd3, 0xf8, 0xc7, + 0xf9, 0xc2, 0x40, 0x76, + 0xe1, 0x48, 0x40, 0x9e, + 0xf6, 0xc2, 0x00, 0x1e, + 0x48, 0x9e, 0xcb, 0xc6, + 0x4c, 0x9e, 0x81, 0x1e, + 0x4e, 0x8e, 0x4e, 0x76, + 0xef, 0x49, 0xfe, 0xf1, + 0xea, 0xc6, 0x4c, 0x9e, + 0x81, 0x1e, 0x4e, 0x8e, + 0x4e, 0x76, 0xef, 0x49, + 0xfe, 0xf1, 0xdf, 0xe7, + 0x40, 0xd4, 0x00, 0x00, + 0xfe, 0xc2, 0x4c, 0x73, + 0xbf, 0x49, 0xc4, 0xf0, + 0x06, 0x76, 0xfa, 0xc2, + 0x32, 0x40, 0xc0, 0xf0, + 0xde, 0xc6, 0xc0, 0x75, + 0xd1, 0x49, 0xd1, 0xf0, + 0xd7, 0xc0, 0xd7, 0xc6, + 0x0c, 0x9e, 0x00, 0x1e, + 0x08, 0x9e, 0xd4, 0xc6, + 0x0a, 0x9e, 0x8f, 0x1e, + 0x0e, 0x8e, 0x0e, 0x76, + 0xef, 0x49, 0xfe, 0xf1, + 0xc4, 0xe7, 0x1a, 0xc6, + 0xc0, 0x67, 0xf0, 0x49, + 0x13, 0xf0, 0xf0, 0x48, + 0xc0, 0x8f, 0xc2, 0x77, + 0x14, 0xc1, 0x14, 0xc6, + 0x24, 0x9e, 0x22, 0x9f, + 0x8c, 0x1e, 0x26, 0x8e, + 0x26, 0x76, 0xef, 0x49, + 0xfe, 0xf1, 0xfb, 0x49, + 0x05, 0xf0, 0x07, 0xc6, + 0xc0, 0x61, 0x10, 0x48, + 0xc0, 0x89, 0x02, 0xc6, + 0x00, 0xbe, 0x7e, 0x36, + 0x6c, 0xb4, 0x90, 0xcc, + 0x08, 0xdc, 0x10, 0xe8, 0x1e, 0x89, 0x02, 0xc0, 0x00, 0xb8, 0xfa, 0x12, 0x18, 0xc0, 0x00, 0x65, @@ -6788,101 +6973,102 @@ static void r8153b_firmware(struct r8152 *tp) 0x41, 0x00, 0xff, 0x00, 0x7f, 0x00, 0x00, 0xe6, 0x60, 0xd3, 0x08, 0xdc, - 0x40, 0x60, 0x80, 0x48, - 0x81, 0x48, 0x82, 0x48, - 0x02, 0xc1, 0x00, 0xb9, - 0x72, 0x16, 0x1c, 0xc6, - 0xc0, 0x61, 0x04, 0x11, - 0x15, 0xf1, 0x19, 0xc6, - 0xc0, 0x61, 0x9c, 0x20, - 0x9c, 0x24, 0x09, 0x11, - 0x0f, 0xf1, 0x14, 0xc6, - 0x01, 0x19, 0xc0, 0x89, - 0x13, 0xc1, 0x13, 0xc6, - 0x24, 0x9e, 0x00, 0x1e, - 0x26, 0x8e, 0x26, 0x76, - 0xef, 0x49, 0xfe, 0xf1, - 0x22, 0x76, 0x08, 0xc1, - 0x22, 0x9e, 0x07, 0xc6, - 0x02, 0xc1, 0x00, 0xb9, - 0x8c, 0x08, 0x18, 0xb4, - 0x4a, 0xb4, 0x90, 0xcc, - 0x80, 0xd4, 0x08, 0xdc, - 0x10, 0xe8, 0xfc, 0xc6, - 0xc0, 0x67, 0xf0, 0x49, - 0x13, 0xf0, 0xf0, 0x48, - 0xc0, 0x8f, 0xc2, 0x77, - 0xf7, 0xc1, 0xf7, 0xc6, - 0x24, 0x9e, 0x22, 0x9f, - 0x8c, 0x1e, 0x26, 0x8e, - 0x26, 0x76, 0xef, 0x49, - 0xfe, 0xf1, 0xfb, 0x49, - 0x05, 0xf0, 0x07, 0xc6, - 0xc0, 0x61, 0x10, 0x48, - 0xc0, 0x89, 0x02, 0xc6, - 0x00, 0xbe, 0x7e, 0x36, - 0x6c, 0xb4, 0x00, 0x00 }; - static u8 pla_patch2_b[] = { - 0x05, 0xe0, 0x1b, 0xe0, - 0x2c, 0xe0, 0x60, 0xe0, - 0x73, 0xe0, 0x15, 0xc6, - 0xc2, 0x64, 0xd2, 0x49, - 0x06, 0xf1, 0xc4, 0x48, - 0xc5, 0x48, 0xc6, 0x48, - 0xc7, 0x48, 0x05, 0xe0, - 0x44, 0x48, 0x45, 0x48, - 0x46, 0x48, 0x47, 0x48, - 0xc2, 0x8c, 0xc0, 0x64, - 0x46, 0x48, 0xc0, 0x8c, - 0x05, 0xc5, 0x02, 0xc4, - 0x00, 0xbc, 0x18, 0x02, - 0x06, 0xdc, 0xb0, 0xc0, - 0x10, 0xc5, 0xa0, 0x77, - 0xa0, 0x74, 0x46, 0x48, - 0x47, 0x48, 0xa0, 0x9c, - 0x0b, 0xc5, 0xa0, 0x74, - 0x44, 0x48, 0x43, 0x48, - 0xa0, 0x9c, 0x05, 0xc5, - 0xa0, 0x9f, 0x02, 0xc5, - 0x00, 0xbd, 0x3c, 0x03, - 0x1c, 0xe8, 0x20, 0xe8, - 0xd4, 0x49, 0x04, 0xf1, - 0xd5, 0x49, 0x20, 0xf1, - 0x28, 0xe0, 0x2a, 0xc7, - 0xe0, 0x75, 0xda, 0x49, - 0x14, 0xf0, 0x27, 0xc7, - 0xe0, 0x75, 0xdc, 0x49, - 0x10, 0xf1, 0x24, 0xc7, - 0xe0, 0x75, 0x25, 0xc7, - 0xe0, 0x74, 0x2c, 0x40, - 0x0a, 0xfa, 0x1f, 0xc7, - 0xe4, 0x75, 0xd0, 0x49, - 0x09, 0xf1, 0x1c, 0xc5, - 0xe6, 0x9d, 0x11, 0x1d, - 0xe4, 0x8d, 0x04, 0xe0, - 0x16, 0xc7, 0x00, 0x1d, - 0xe4, 0x8d, 0xe0, 0x8e, - 0x11, 0x1d, 0xe0, 0x8d, - 0x07, 0xe0, 0x0c, 0xc7, - 0xe0, 0x75, 0xda, 0x48, - 0xe0, 0x9d, 0x0b, 0xc7, - 0xe4, 0x8e, 0x02, 0xc4, - 0x00, 0xbc, 0x28, 0x03, - 0x02, 0xc4, 0x00, 0xbc, - 0x14, 0x03, 0x12, 0xe8, - 0x4e, 0xe8, 0x1c, 0xe6, - 0x20, 0xe4, 0x80, 0x02, - 0xa4, 0xc0, 0x12, 0xc2, - 0x40, 0x73, 0xb0, 0x49, - 0x08, 0xf0, 0xb8, 0x49, - 0x06, 0xf0, 0xb8, 0x48, - 0x40, 0x9b, 0x0b, 0xc2, - 0x40, 0x76, 0x05, 0xe0, - 0x02, 0x61, 0x02, 0xc3, - 0x00, 0xbb, 0x0a, 0x0a, + 0x1b, 0xc4, 0x80, 0x75, + 0x08, 0x15, 0x04, 0xf0, + 0x01, 0x05, 0x80, 0x9d, + 0x0f, 0xe0, 0x00, 0x1d, + 0x80, 0x9d, 0x25, 0xc4, + 0x80, 0x75, 0xd8, 0x22, + 0xdc, 0x26, 0x01, 0x15, + 0x04, 0xf1, 0x0d, 0xc4, + 0x11, 0x1d, 0x80, 0x8d, + 0x14, 0x1e, 0xe5, 0x8e, + 0x04, 0xe0, 0xe5, 0x66, + 0x62, 0x48, 0xe5, 0x8e, 0x02, 0xc3, 0x00, 0xbb, - 0x1a, 0x0a, 0x98, 0xd3, - 0x1e, 0xfc, 0xfe, 0xc0, + 0x8c, 0x06, 0x50, 0xd3, + 0x4c, 0xb4, 0x11, 0xc0, + 0x00, 0x71, 0x98, 0x20, + 0x9c, 0x24, 0x01, 0x11, + 0x06, 0xf1, 0x0a, 0xc6, + 0x01, 0x1d, 0xc6, 0x8d, + 0x19, 0x1d, 0xc1, 0x8d, + 0x04, 0xc0, 0x02, 0xc1, + 0x00, 0xb9, 0xa2, 0x12, + 0xc0, 0xd4, 0x04, 0xe4, + 0xb4, 0xbb, 0xec, 0xc6, + 0x00, 0x1d, 0xc0, 0x8d, + 0xfb, 0xc6, 0x14, 0x1d, + 0xc5, 0x8d, 0x04, 0xc6, + 0x02, 0xc5, 0x00, 0xbd, + 0xd2, 0x03, 0x40, 0xb4 }; + static u8 pla_patch2_b[] = { + 0x10, 0xe0, 0x26, 0xe0, + 0x37, 0xe0, 0x6b, 0xe0, + 0x7e, 0xe0, 0xcb, 0xe0, + 0xcd, 0xe0, 0xcf, 0xe0, + 0xd1, 0xe0, 0xd3, 0xe0, + 0xd5, 0xe0, 0xd7, 0xe0, + 0xd9, 0xe0, 0xdb, 0xe0, + 0xdd, 0xe0, 0xdf, 0xe0, + 0x15, 0xc6, 0xc2, 0x64, + 0xd2, 0x49, 0x06, 0xf1, + 0xc4, 0x48, 0xc5, 0x48, + 0xc6, 0x48, 0xc7, 0x48, + 0x05, 0xe0, 0x44, 0x48, + 0x45, 0x48, 0x46, 0x48, + 0x47, 0x48, 0xc2, 0x8c, + 0xc0, 0x64, 0x46, 0x48, + 0xc0, 0x8c, 0x05, 0xc5, + 0x02, 0xc4, 0x00, 0xbc, + 0x18, 0x02, 0x06, 0xdc, + 0xb0, 0xc0, 0x10, 0xc5, + 0xa0, 0x77, 0xa0, 0x74, + 0x46, 0x48, 0x47, 0x48, + 0xa0, 0x9c, 0x0b, 0xc5, + 0xa0, 0x74, 0x44, 0x48, + 0x43, 0x48, 0xa0, 0x9c, + 0x05, 0xc5, 0xa0, 0x9f, + 0x02, 0xc5, 0x00, 0xbd, + 0x3c, 0x03, 0x1c, 0xe8, + 0x20, 0xe8, 0xd4, 0x49, + 0x04, 0xf1, 0xd5, 0x49, + 0x20, 0xf1, 0x28, 0xe0, + 0x2a, 0xc7, 0xe0, 0x75, + 0xda, 0x49, 0x14, 0xf0, + 0x27, 0xc7, 0xe0, 0x75, + 0xdc, 0x49, 0x10, 0xf1, + 0x24, 0xc7, 0xe0, 0x75, + 0x25, 0xc7, 0xe0, 0x74, + 0x2c, 0x40, 0x0a, 0xfa, + 0x1f, 0xc7, 0xe4, 0x75, + 0xd0, 0x49, 0x09, 0xf1, + 0x1c, 0xc5, 0xe6, 0x9d, + 0x11, 0x1d, 0xe4, 0x8d, + 0x04, 0xe0, 0x16, 0xc7, + 0x00, 0x1d, 0xe4, 0x8d, + 0xe0, 0x8e, 0x11, 0x1d, + 0xe0, 0x8d, 0x07, 0xe0, + 0x0c, 0xc7, 0xe0, 0x75, + 0xda, 0x48, 0xe0, 0x9d, + 0x0b, 0xc7, 0xe4, 0x8e, + 0x02, 0xc4, 0x00, 0xbc, + 0x28, 0x03, 0x02, 0xc4, + 0x00, 0xbc, 0x14, 0x03, + 0x12, 0xe8, 0x4e, 0xe8, + 0x1c, 0xe6, 0x20, 0xe4, + 0x80, 0x02, 0xa4, 0xc0, + 0x12, 0xc2, 0x40, 0x73, + 0xb0, 0x49, 0x08, 0xf0, + 0xb8, 0x49, 0x06, 0xf0, + 0xb8, 0x48, 0x40, 0x9b, + 0x0b, 0xc2, 0x40, 0x76, + 0x05, 0xe0, 0x02, 0x61, + 0x02, 0xc3, 0x00, 0xbb, + 0x0a, 0x0a, 0x02, 0xc3, + 0x00, 0xbb, 0x1a, 0x0a, + 0x98, 0xd3, 0x1e, 0xfc, + 0x1f, 0xe8, 0xfd, 0xc0, 0x02, 0x62, 0xa0, 0x48, 0x02, 0x8a, 0x00, 0x72, 0xa0, 0x49, 0x11, 0xf0, @@ -6895,58 +7081,113 @@ static void r8153b_firmware(struct r8152 *tp) 0x9f, 0x48, 0x02, 0xe0, 0x1f, 0x48, 0x00, 0x99, 0x02, 0xc2, 0x00, 0xba, - 0xda, 0x0e, 0x08, 0xe9 }; + 0xda, 0x0e, 0x08, 0xe9, + 0x08, 0xea, 0x34, 0xd3, + 0xe8, 0xd4, 0x00, 0xb4, + 0x01, 0xb4, 0x02, 0xb4, + 0xf9, 0xc1, 0x20, 0x62, + 0x2e, 0x21, 0x2f, 0x25, + 0xa0, 0x49, 0x23, 0xf0, + 0xf4, 0xc0, 0xf4, 0xc2, + 0x04, 0x9a, 0x00, 0x1a, + 0x06, 0x8a, 0x06, 0x72, + 0xaf, 0x49, 0xfe, 0xf1, + 0x00, 0x72, 0xa1, 0x49, + 0x18, 0xf0, 0xeb, 0xc2, + 0x04, 0x9a, 0x00, 0x1a, + 0x06, 0x8a, 0x06, 0x72, + 0xaf, 0x49, 0xfe, 0xf1, + 0x00, 0x72, 0xa1, 0x48, + 0x00, 0x9a, 0x81, 0x1a, + 0x06, 0x8a, 0x06, 0x72, + 0xaf, 0x49, 0xfe, 0xf1, + 0x00, 0x72, 0x21, 0x48, + 0x00, 0x9a, 0x81, 0x1a, + 0x06, 0x8a, 0x06, 0x72, + 0xaf, 0x49, 0xfe, 0xf1, + 0x02, 0xb0, 0x01, 0xb0, + 0x00, 0xb0, 0x80, 0xff, + 0x02, 0xc0, 0x00, 0xb8, + 0x3a, 0x4e, 0x02, 0xc0, + 0x00, 0xb8, 0x3a, 0x4e, + 0x02, 0xc0, 0x00, 0xb8, + 0x3a, 0x4e, 0x02, 0xc0, + 0x00, 0xb8, 0x00, 0x00, + 0x02, 0xc0, 0x00, 0xb8, + 0x00, 0x00, 0x02, 0xc0, + 0x00, 0xb8, 0x00, 0x00, + 0x02, 0xc0, 0x00, 0xb8, + 0x00, 0x00, 0x02, 0xc0, + 0x00, 0xb8, 0x00, 0x00, + 0x02, 0xc0, 0x00, 0xb8, + 0x00, 0x00, 0x02, 0xc0, + 0x00, 0xb8, 0x00, 0x00, + 0x02, 0xc0, 0x00, 0xb8, + 0x00, 0x00, 0x00, 0x00 }; + u8 new_ver; - rtl_clear_bp(tp, MCU_TYPE_USB); + rtl_fw_ver_erase(tp); - /* enable fc timer and set timer to 1 second. */ - ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, - CTRL_TIMER_EN | (1000 / 8)); + new_ver = 7; + if (rtl_check_fw_ver_ok(tp, USB_FW_USB_VER, new_ver)) { + rtl_clear_bp(tp, MCU_TYPE_USB); - generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb_patch2_b), - usb_patch2_b, MCU_TYPE_USB); + /* enable fc timer and set timer to 1 second. */ + ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, + CTRL_TIMER_EN | (1000 / 8)); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xa000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x2a20); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x28a6); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x1dee); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x16c2); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x1c94); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x19f0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x340c); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x335e); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x12f8); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x419e); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x23f4); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x186e); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x19e6); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x1670); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x088a); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x35a8); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0xffff); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd7, 0x04); + generic_ocp_write(tp, 0xe600, 0xff, + sizeof(usb_patch2_b), usb_patch2_b, + MCU_TYPE_USB); - rtl_clear_bp(tp, MCU_TYPE_PLA); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xa000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x3d86); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x088a); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x1dee); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x16c2); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x1c94); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x19f0); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x27e0); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x35a8); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x12f8); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x419e); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x23f4); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x186e); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x19e6); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x0674); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x12a0); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x03d0); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0xffff); + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_USB_VER, + new_ver); + } - generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch2_b), - pla_patch2_b, MCU_TYPE_PLA); + new_ver = 3; + if (rtl_check_fw_ver_ok(tp, USB_FW_PLA_VER, new_ver)) { + rtl_clear_bp(tp, MCU_TYPE_PLA); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x0216); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x0332); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x030c); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x0a08); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x0ec0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x001e); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd6, 0x02); + generic_ocp_write(tp, 0xf800, 0xff, + sizeof(pla_patch2_b), pla_patch2_b, + MCU_TYPE_PLA); - if (ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1) & BND_MASK) { - ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BP_EN); - ocp_data |= BIT(0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, ocp_data); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x0216); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x0332); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x030c); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x0a08); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x0ec0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x001e); + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_PLA_VER, + new_ver); + + if (ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1) & BND_MASK) { + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BP_EN); + ocp_data |= BIT(0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, ocp_data); + } } ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); @@ -7110,62 +7351,75 @@ static void r8153b_firmware(struct r8152 *tp) 0x00, 0xb8, 0x00, 0x00, 0x02, 0xc0, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00 }; + u8 new_ver; - rtl_clear_bp(tp, MCU_TYPE_PLA); + rtl_fw_ver_erase(tp); - generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch3_a), - pla_patch3_a, MCU_TYPE_PLA); + new_ver = 2; + if (rtl_check_fw_ver_ok(tp, USB_FW_PLA_VER, new_ver)) { + rtl_clear_bp(tp, MCU_TYPE_PLA); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x2be6); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x2bac); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x2bd4); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x083c); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x0214); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_8, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_9, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_10, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_11, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_12, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_13, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_14, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_15, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP2_EN, 0x001f); + generic_ocp_write(tp, 0xf800, 0xff, + sizeof(pla_patch3_a), pla_patch3_a, + MCU_TYPE_PLA); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd6, 0x02); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x2be6); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x2bac); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x2bd4); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x083c); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x0214); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_8, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_9, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_10, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_11, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_12, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_13, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_14, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_15, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP2_EN, 0x001f); - rtl_clear_bp(tp, MCU_TYPE_USB); + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_PLA_VER, + new_ver); + } - /* enable fc timer and set timer to 1 second. */ - ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, - CTRL_TIMER_EN | (1000 / 8)); + new_ver = 2; + if (rtl_check_fw_ver_ok(tp, USB_FW_USB_VER, new_ver)) { + rtl_clear_bp(tp, MCU_TYPE_USB); - generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb_patch3_a), - usb_patch3_a, MCU_TYPE_USB); + /* enable fc timer and set timer to 1 second. */ + ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, + CTRL_TIMER_EN | (1000 / 8)); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xa000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x02ce); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x5cda); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x0834); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x1bec); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x000f); + generic_ocp_write(tp, 0xe600, 0xff, + sizeof(usb_patch3_a), usb_patch3_a, + MCU_TYPE_USB); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd7, 0x02); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xa000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x02ce); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x5cda); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x0834); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x1bec); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x000f); + + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_USB_VER, + new_ver); + } ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); ocp_data |= FLOW_CTRL_PATCH_2; @@ -8869,6 +9123,28 @@ static void rtl8153_change_mtu(struct r8152 *tp) ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); } +static void r8153_lanwake_clr_en(struct r8152 *tp, bool enable) +{ + u32 ocp_data; + + if (enable) { + /* Enable the feature that the MCU could clear the lanwake */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); + ocp_data |= LANWAKE_CLR_EN; + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); + + /* Clear lanwake */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); + ocp_data &= ~LANWAKE_PIN; + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); + } else { + /* Disable the feature that the MCU could clear the lanwake */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); + ocp_data &= ~LANWAKE_CLR_EN; + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); + } +} + static void r8153_first_init(struct r8152 *tp) { u32 ocp_data; @@ -8915,6 +9191,8 @@ static void r8153_first_init(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_NORMAL); /* TX share fifo free credit full threshold */ ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TXFIFO_CTRL, TXFIFO_THR_NORMAL2); + + r8153_lanwake_clr_en(tp, true); } static void r8153_enter_oob(struct r8152 *tp) @@ -8925,6 +9203,11 @@ static void r8153_enter_oob(struct r8152 *tp) ocp_data &= ~NOW_IS_OOB; ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); + /* RX FIFO settings for OOB */ + ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL0, RXFIFO_THR1_OOB); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL1, RXFIFO_THR2_OOB); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_CTRL2, RXFIFO_THR3_OOB); + rtl_disable(tp); rtl_reset_bmu(tp); @@ -8936,7 +9219,7 @@ static void r8153_enter_oob(struct r8152 *tp) wait_oob_link_list_ready(tp); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu)); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, 1522); ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_DEFAULT); switch (tp->version) { @@ -8982,6 +9265,8 @@ static void r8153_enter_oob(struct r8152 *tp) ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ocp_data |= RCR_APM | RCR_AM | RCR_AB; ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); + + r8153_lanwake_clr_en(tp, false); } static void rtl8153_disable(struct r8152 *tp) @@ -8992,6 +9277,25 @@ static void rtl8153_disable(struct r8152 *tp) r8153_aldps_en(tp, true); } +static u32 fc_pause_on_auto(struct r8152 *tp) +{ + return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024); +} + +static u32 fc_pause_off_auto(struct r8152 *tp) +{ + return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024); +} + +static void r8156_fc_parameter(struct r8152 *tp) +{ + u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp); + u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp); + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16); +} + static int rtl8156_enable(struct r8152 *tp) { u32 ocp_data; @@ -9000,6 +9304,7 @@ static int rtl8156_enable(struct r8152 *tp) if (test_bit(RTL8152_UNPLUG, &tp->flags)) return -ENODEV; + r8156_fc_parameter(tp); set_tx_qlen(tp); rtl_set_eee_plus(tp); r8153_set_rx_early_timeout(tp); @@ -9047,9 +9352,24 @@ static int rtl8156_enable(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_USB, USB_L1_CTRL, ocp_data); } + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); + ocp_data &= ~FC_PATCH_TASK; + ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); + usleep_range(1000, 2000); + ocp_data |= FC_PATCH_TASK; + ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); + return rtl_enable(tp); } +static void rtl8156_disable(struct r8152 *tp) +{ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 0); + + rtl8153_disable(tp); +} + static int rtl8156b_enable(struct r8152 *tp) { u32 ocp_data; @@ -9334,14 +9654,6 @@ static void rtl8153_up(struct r8152 *tp) r8153_aldps_en(tp, false); r8153_first_init(tp); - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); - ocp_data |= LANWAKE_CLR_EN; - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); - - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); - ocp_data &= ~LANWAKE_PIN; - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SSPHYLINK1); ocp_data &= ~DELAY_PHY_PWR_CHG; ocp_write_word(tp, MCU_TYPE_USB, USB_SSPHYLINK1, ocp_data); @@ -9364,17 +9676,11 @@ static void rtl8153_up(struct r8152 *tp) static void rtl8153_down(struct r8152 *tp) { - u32 ocp_data; - if (test_bit(RTL8152_UNPLUG, &tp->flags)) { rtl_drop_queued_tx(tp); return; } - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); - ocp_data &= ~LANWAKE_CLR_EN; - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); - r8153_u1u2en(tp, false); r8153_u2p3en(tp, false); r8153_power_cut_en(tp, false); @@ -9500,38 +9806,6 @@ static void rtl8153c_up(struct r8152 *tp) r8153b_u1u2en(tp, true); } -static inline u32 fc_pause_on_auto(struct r8152 *tp) -{ - return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 6 * 1024); -} - -static inline u32 fc_pause_off_auto(struct r8152 *tp) -{ - return (ALIGN(mtu_to_size(tp->netdev->mtu), 1024) + 14 * 1024); -} - -static void r8156_fc_parameter(struct r8152 *tp) -{ - u32 pause_on = tp->fc_pause_on ? tp->fc_pause_on : fc_pause_on_auto(tp); - u32 pause_off = tp->fc_pause_off ? tp->fc_pause_off : fc_pause_off_auto(tp); - - switch (tp->version) { - case RTL_VER_10: - case RTL_VER_11: - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 8); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 8); - break; - case RTL_VER_12: - case RTL_VER_13: - case RTL_VER_15: - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, pause_on / 16); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, pause_off / 16); - break; - default: - break; - } -} - static void rtl8156_change_mtu(struct r8152 *tp) { u32 rx_max_size = mtu_to_size(tp->netdev->mtu); @@ -9636,19 +9910,35 @@ static void rtl8156_down(struct r8152 *tp) ocp_data &= ~NOW_IS_OOB; ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); + /* RX FIFO settings for OOB */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RXFIFO_FULL, 64 / 16); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_FULL, 1024 / 16); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RX_FIFO_EMPTY, 4096 / 16); + rtl_disable(tp); rtl_reset_bmu(tp); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, 1522); + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_DEFAULT); + /* Clear teredo wake event. bit[15:8] is the teredo wakeup * type. Set it to zero. bits[7:0] are the W1C bits about * the events. Set them to all 1 to clear them. */ ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_WAKE_BASE, 0x00ff); + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_BDC_CR); + ocp_data |= ALDPS_PROXY_MODE; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BDC_CR, ocp_data); + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - ocp_data |= NOW_IS_OOB; + ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB; ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data); + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); + ocp_data |= MCU_BORW_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); + rtl_rx_vlan_en(tp, true); rxdy_gated_en(tp, false); @@ -10091,10 +10381,11 @@ static int rtl8152_close(struct net_device *netdev) rtl_speed_down(tp); mutex_unlock(&tp->control); - - usb_autopm_put_interface(tp->intf); } + if (!res) + usb_autopm_put_interface(tp->intf); + free_all_mem(tp); return res; @@ -10142,6 +10433,8 @@ static void r8152b_init(struct r8152 *tp) } #endif + data = r8153_phy_status(tp, 0); + data = r8152_mdio_read(tp, MII_BMCR); if (data & BMCR_PDOWN) { data &= ~BMCR_PDOWN; @@ -10297,13 +10590,7 @@ static void r8153_init(struct r8152 *tp) r8153_u1u2en(tp, true); usb_enable_lpm(tp->udev); - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); - ocp_data |= LANWAKE_CLR_EN; - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); - - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); - ocp_data &= ~LANWAKE_PIN; - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); + r8153_lanwake_clr_en(tp, true); /* rx aggregation */ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); @@ -10383,17 +10670,7 @@ static void r8153b_init(struct r8152 *tp) ocp_data |= POLL_LINK_CHG; ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data); - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); - ocp_data |= LANWAKE_CLR_EN; - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); - - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); - ocp_data &= ~LANWAKE_PIN; - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); - - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); - ocp_data &= ~LANWAKE_CLR_EN; - ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); + r8153_lanwake_clr_en(tp, true); if (tp->udev->descriptor.idVendor == VENDOR_ID_LENOVO && tp->udev->descriptor.idProduct == 0x3069) @@ -10405,7 +10682,7 @@ static void r8153b_init(struct r8152 *tp) usb_enable_lpm(tp->udev); /* MAC clock speed down */ - r8153_mac_clk_speed_down(tp, true); + r8153_mac_clk_speed_down(tp, false); r8153b_mcu_spdown_en(tp, false); @@ -10543,49 +10820,44 @@ static void r8156_patch_code(struct r8152 *tp) } else if (tp->version == RTL_VER_11) { u32 ocp_data; static u8 usb_patch3_b[] = { - 0x10, 0xe0, 0x28, 0xe0, - 0x3d, 0xe0, 0x85, 0xe0, - 0x99, 0xe0, 0xb4, 0xe0, - 0xd4, 0xe0, 0xfa, 0xe0, - 0x20, 0xe1, 0x39, 0xe1, - 0x65, 0xe1, 0xab, 0xe1, - 0xba, 0xe1, 0xcc, 0xe1, - 0xe3, 0xe1, 0xc0, 0xe2, - 0x18, 0xc0, 0x00, 0x75, - 0xd8, 0x49, 0x0e, 0xf0, - 0x10, 0xc0, 0x10, 0xc5, - 0x00, 0x1e, 0x08, 0x9e, - 0x0c, 0x9d, 0x0e, 0xc6, - 0x0a, 0x9e, 0x8f, 0x1c, - 0x0e, 0x8c, 0x0e, 0x74, - 0xcf, 0x49, 0xfe, 0xf1, - 0x45, 0xe8, 0x02, 0xc0, - 0x00, 0xb8, 0xf0, 0x4b, - 0x00, 0xdc, 0x24, 0xe4, - 0x04, 0xe4, 0x80, 0x02, - 0x34, 0xd3, 0xff, 0xc3, - 0x60, 0x72, 0xa8, 0x49, - 0x0e, 0xf0, 0xf7, 0xc3, - 0xf7, 0xc2, 0x00, 0x1c, - 0x68, 0x9c, 0xf6, 0xc4, - 0x6a, 0x9c, 0x6c, 0x9a, - 0x8f, 0x1c, 0x6e, 0x8c, - 0x6e, 0x74, 0xcf, 0x49, - 0xfe, 0xf1, 0x2c, 0xe8, - 0x04, 0xc0, 0x02, 0xc2, - 0x00, 0xba, 0x9a, 0x3c, - 0x80, 0xc3, 0x26, 0xe8, + 0x10, 0xe0, 0x12, 0xe0, + 0x33, 0xe0, 0x7d, 0xe0, + 0x92, 0xe0, 0xae, 0xe0, + 0xce, 0xe0, 0x23, 0xe1, + 0x3f, 0xe1, 0x58, 0xe1, + 0x84, 0xe1, 0xca, 0xe1, + 0xd9, 0xe1, 0xeb, 0xe1, + 0x02, 0xe2, 0xe0, 0xe2, + 0x02, 0xc0, 0x00, 0xb8, + 0xf0, 0x4b, 0x1c, 0xc6, + 0xc0, 0x61, 0x04, 0x11, + 0x15, 0xf1, 0x19, 0xc6, + 0xc0, 0x61, 0x9c, 0x20, + 0x9c, 0x24, 0x09, 0x11, + 0x0f, 0xf1, 0x14, 0xc6, + 0x01, 0x19, 0xc0, 0x89, + 0x13, 0xc1, 0x13, 0xc6, + 0x24, 0x9e, 0x00, 0x1e, + 0x26, 0x8e, 0x26, 0x76, + 0xef, 0x49, 0xfe, 0xf1, + 0x22, 0x76, 0x08, 0xc1, + 0x22, 0x9e, 0x07, 0xc6, + 0x02, 0xc1, 0x00, 0xb9, + 0x9e, 0x09, 0x18, 0xb4, + 0x4a, 0xb4, 0x90, 0xcc, + 0x80, 0xd4, 0x08, 0xdc, + 0x10, 0xe8, 0x28, 0xe8, 0x23, 0xc7, 0x21, 0xc2, 0xec, 0x9a, 0x00, 0x19, 0xee, 0x89, 0xee, 0x71, 0x9f, 0x49, 0xfe, 0xf1, 0xea, 0x71, 0x9f, 0x49, - 0x14, 0xf0, 0xda, 0xc2, + 0x14, 0xf0, 0x1a, 0xc2, 0xec, 0x9a, 0x00, 0x19, 0xe8, 0x99, 0x81, 0x19, 0xee, 0x89, 0xee, 0x71, 0x9f, 0x49, 0xfe, 0xf1, - 0xd2, 0xc2, 0xec, 0x9a, + 0x12, 0xc2, 0xec, 0x9a, 0x00, 0x19, 0x98, 0x20, 0xe8, 0x99, 0x82, 0x19, 0xee, 0x89, 0xee, 0x71, @@ -10593,17 +10865,18 @@ static void r8156_patch_code(struct r8152 *tp) 0x06, 0xc3, 0x02, 0xc2, 0x00, 0xba, 0x3e, 0x29, 0x4c, 0xe8, 0x00, 0xdc, - 0x00, 0xd4, 0x00, 0xb4, + 0x00, 0xd4, 0x24, 0xe4, + 0x04, 0xe4, 0x00, 0xb4, 0x04, 0xb4, 0x05, 0xb4, - 0x06, 0xb4, 0xbf, 0xc0, + 0x06, 0xb4, 0x51, 0xc0, 0x00, 0x75, 0xd9, 0x49, - 0x17, 0xf0, 0xb7, 0xc0, - 0xb8, 0xc5, 0x00, 0x1e, + 0x17, 0xf0, 0x30, 0xc0, + 0xf6, 0xc5, 0x00, 0x1e, 0x68, 0x23, 0x08, 0x9e, 0x0c, 0x9d, 0x82, 0x1c, 0x0e, 0x8c, 0x0e, 0x74, 0xcf, 0x49, 0xfe, 0xf1, - 0xac, 0xc0, 0xad, 0xc5, + 0x25, 0xc0, 0xeb, 0xc5, 0x11, 0x1e, 0x68, 0x23, 0x08, 0x9e, 0x0c, 0x9d, 0x82, 0x1c, 0x0e, 0x8c, @@ -10611,40 +10884,41 @@ static void r8156_patch_code(struct r8152 *tp) 0xfe, 0xf1, 0x06, 0xb0, 0x05, 0xb0, 0x04, 0xb0, 0x00, 0xb0, 0x80, 0xff, - 0xa0, 0xc0, 0x00, 0x75, + 0x32, 0xc0, 0x00, 0x75, 0xd8, 0x49, 0x0d, 0xf0, - 0x98, 0xc0, 0x98, 0xc5, + 0x11, 0xc0, 0xd6, 0xc5, 0x00, 0x1e, 0x08, 0x9e, - 0x97, 0xc6, 0x0a, 0x9e, + 0x73, 0xc6, 0x0a, 0x9e, 0x0c, 0x9d, 0x8f, 0x1c, 0x0e, 0x8c, 0x0e, 0x74, 0xcf, 0x49, 0xfe, 0xf1, 0x04, 0xc0, 0x02, 0xc1, 0x00, 0xb9, 0x00, 0x1d, - 0x20, 0xd4, 0xc8, 0xef, - 0x8a, 0xc0, 0x00, 0x75, - 0xd8, 0x48, 0x00, 0x9d, - 0xc1, 0xc7, 0x15, 0xc2, - 0xec, 0x9a, 0x00, 0x19, - 0xe8, 0x9a, 0x81, 0x19, - 0xee, 0x89, 0xee, 0x71, - 0x9f, 0x49, 0xfe, 0xf1, - 0x2d, 0xc1, 0xec, 0x99, + 0x20, 0xd4, 0x00, 0xdc, + 0xc7, 0xef, 0x1b, 0xc0, + 0x00, 0x75, 0xd8, 0x48, + 0x00, 0x9d, 0xbe, 0xc7, + 0x15, 0xc2, 0xec, 0x9a, + 0x00, 0x19, 0xe8, 0x9a, 0x81, 0x19, 0xee, 0x89, 0xee, 0x71, 0x9f, 0x49, - 0xfe, 0xf1, 0x04, 0xc3, - 0x02, 0xc2, 0x00, 0xba, - 0x3a, 0x27, 0xc0, 0xd4, - 0x24, 0xe4, 0xc0, 0x88, + 0xfe, 0xf1, 0x2e, 0xc1, + 0xec, 0x99, 0x81, 0x19, + 0xee, 0x89, 0xee, 0x71, + 0x9f, 0x49, 0xfe, 0xf1, + 0x04, 0xc3, 0x02, 0xc2, + 0x00, 0xba, 0x3a, 0x27, + 0xc0, 0xd4, 0x24, 0xe4, + 0x34, 0xd3, 0xc0, 0x88, 0x1e, 0xc6, 0xc0, 0x70, 0x8f, 0x49, 0x0e, 0xf0, - 0x8f, 0x48, 0x68, 0xc6, + 0x8f, 0x48, 0x3f, 0xc6, 0xca, 0x98, 0x11, 0x18, 0xc8, 0x98, 0x16, 0xc0, 0xcc, 0x98, 0x8f, 0x18, 0xce, 0x88, 0xce, 0x70, 0x8f, 0x49, 0xfe, 0xf1, - 0x0b, 0xe0, 0x5c, 0xc6, + 0x0b, 0xe0, 0x33, 0xc6, 0x00, 0x18, 0xc8, 0x98, 0x0b, 0xc0, 0xcc, 0x98, 0x81, 0x18, 0xce, 0x88, @@ -10652,167 +10926,186 @@ static void r8156_patch_code(struct r8152 *tp) 0xfe, 0xf1, 0x02, 0xc0, 0x00, 0xb8, 0xbc, 0x21, 0x40, 0xd3, 0x20, 0xe4, - 0x4c, 0xc2, 0x40, 0x71, - 0x98, 0x48, 0x99, 0x48, - 0x40, 0x99, 0x48, 0xc2, - 0x00, 0x19, 0x98, 0x20, - 0x48, 0x99, 0x1d, 0xc1, - 0x4c, 0x99, 0x82, 0x19, - 0x4e, 0x89, 0x4e, 0x71, - 0x9f, 0x49, 0xfe, 0xf1, - 0x3d, 0xc2, 0x00, 0x19, - 0x48, 0x99, 0xec, 0xc1, - 0x4c, 0x99, 0x81, 0x19, - 0x4e, 0x89, 0x4e, 0x71, - 0x9f, 0x49, 0xfe, 0xf1, - 0x0b, 0xc1, 0x4c, 0x99, - 0x81, 0x19, 0x4e, 0x89, - 0x4e, 0x71, 0x9f, 0x49, - 0xfe, 0xf1, 0x02, 0x71, - 0x02, 0xc2, 0x00, 0xba, - 0xfe, 0x4e, 0x24, 0xe4, - 0x04, 0xe4, 0x25, 0xc2, - 0x40, 0x71, 0x98, 0x48, - 0x99, 0x48, 0x40, 0x99, - 0x21, 0xc2, 0x00, 0x19, - 0x98, 0x20, 0x48, 0x99, - 0xf6, 0xc1, 0x4c, 0x99, - 0x82, 0x19, 0x4e, 0x89, - 0x4e, 0x71, 0x9f, 0x49, - 0xfe, 0xf1, 0x16, 0xc2, - 0x00, 0x19, 0x48, 0x99, - 0xc5, 0xc1, 0x4c, 0x99, - 0x81, 0x19, 0x4e, 0x89, - 0x4e, 0x71, 0x9f, 0x49, - 0xfe, 0xf1, 0xe4, 0xc1, - 0x4c, 0x99, 0x81, 0x19, - 0x4e, 0x89, 0x4e, 0x71, - 0x9f, 0x49, 0xfe, 0xf1, - 0x02, 0x71, 0x02, 0xc2, - 0x00, 0xba, 0x00, 0x4e, - 0x34, 0xd3, 0x00, 0xdc, - 0x3d, 0xef, 0x18, 0xc0, - 0x00, 0x72, 0xa8, 0x49, - 0x0d, 0xf0, 0x11, 0xc0, - 0x11, 0xc2, 0x00, 0x19, - 0x08, 0x99, 0x0c, 0x9a, - 0x0e, 0xc1, 0x0a, 0x99, - 0x8f, 0x1b, 0x0e, 0x8b, - 0x0e, 0x73, 0xbf, 0x49, - 0xfe, 0xf1, 0x04, 0xc0, - 0x02, 0xc2, 0x00, 0xba, - 0x64, 0x62, 0x02, 0xcf, - 0x00, 0xdc, 0x24, 0xe4, - 0x80, 0x02, 0x34, 0xd3, - 0x2c, 0xc3, 0x60, 0x70, - 0x80, 0x49, 0xfd, 0xf0, - 0x27, 0xc3, 0x66, 0x60, - 0x80, 0x48, 0x02, 0x48, - 0x66, 0x88, 0x00, 0x48, - 0x82, 0x48, 0x66, 0x88, - 0x1b, 0xc3, 0x60, 0x70, - 0x17, 0xc4, 0x88, 0x98, - 0x14, 0xc0, 0x8c, 0x98, - 0x83, 0x18, 0x8e, 0x88, - 0x8e, 0x70, 0x8f, 0x49, - 0xfe, 0xf1, 0x62, 0x70, - 0x8a, 0x98, 0x0d, 0xc0, - 0x8c, 0x98, 0x84, 0x18, + 0x29, 0xc0, 0x01, 0x66, + 0x05, 0x16, 0x3e, 0xf0, + 0x25, 0x16, 0x40, 0xf0, + 0x09, 0x16, 0x23, 0xf0, + 0x16, 0xe0, 0x1a, 0xc2, + 0x40, 0x76, 0xe1, 0x48, + 0x40, 0x9e, 0x17, 0xc2, + 0x00, 0x1e, 0x48, 0x9e, + 0xef, 0xc6, 0x4c, 0x9e, + 0x81, 0x1e, 0x4e, 0x8e, + 0x4e, 0x76, 0xef, 0x49, + 0xfe, 0xf1, 0x0b, 0xc6, + 0x4c, 0x9e, 0x81, 0x1e, + 0x4e, 0x8e, 0x4e, 0x76, + 0xef, 0x49, 0xfe, 0xf1, + 0x90, 0x49, 0x02, 0xc7, + 0x00, 0xbf, 0x64, 0x39, + 0x24, 0xe4, 0x34, 0xd3, + 0x00, 0xdc, 0x00, 0xdc, + 0x24, 0xe4, 0x80, 0x02, + 0x34, 0xd3, 0x80, 0xc3, + 0xf9, 0xc2, 0x40, 0x76, + 0xe1, 0x48, 0x40, 0x9e, + 0xf6, 0xc2, 0x00, 0x1e, + 0x48, 0x9e, 0xce, 0xc6, + 0x4c, 0x9e, 0x81, 0x1e, + 0x4e, 0x8e, 0x4e, 0x76, + 0xef, 0x49, 0xfe, 0xf1, + 0xea, 0xc6, 0x4c, 0x9e, + 0x81, 0x1e, 0x4e, 0x8e, + 0x4e, 0x76, 0xef, 0x49, + 0xfe, 0xf1, 0xdf, 0xe7, + 0x40, 0xd4, 0xff, 0xc2, + 0x4c, 0x73, 0xbf, 0x49, + 0xc5, 0xf0, 0xe3, 0xc6, + 0xc0, 0x75, 0xd1, 0x49, + 0xd6, 0xf0, 0xdc, 0xc0, + 0xdc, 0xc6, 0x0c, 0x9e, + 0x00, 0x1e, 0x08, 0x9e, + 0xd9, 0xc6, 0x0a, 0x9e, + 0x8f, 0x1e, 0x0e, 0x8e, + 0x0e, 0x76, 0xef, 0x49, + 0xfe, 0xf1, 0xc9, 0xe7, + 0x1a, 0xc6, 0xc0, 0x67, + 0xf0, 0x49, 0x13, 0xf0, + 0xf0, 0x48, 0xc0, 0x8f, + 0xc2, 0x77, 0x14, 0xc1, + 0x14, 0xc6, 0x24, 0x9e, + 0x22, 0x9f, 0x8c, 0x1e, + 0x26, 0x8e, 0x26, 0x76, + 0xef, 0x49, 0xfe, 0xf1, + 0xfb, 0x49, 0x05, 0xf0, + 0x07, 0xc6, 0xc0, 0x61, + 0x10, 0x48, 0xc0, 0x89, + 0x02, 0xc6, 0x00, 0xbe, + 0x96, 0x52, 0x6c, 0xb4, + 0x90, 0xcc, 0x08, 0xdc, + 0x10, 0xe8, 0x16, 0xef, + 0x18, 0xc0, 0x00, 0x72, + 0xa8, 0x49, 0x0d, 0xf0, + 0x11, 0xc0, 0x11, 0xc2, + 0x00, 0x19, 0x08, 0x99, + 0x0c, 0x9a, 0x0e, 0xc1, + 0x0a, 0x99, 0x8f, 0x1b, + 0x0e, 0x8b, 0x0e, 0x73, + 0xbf, 0x49, 0xfe, 0xf1, + 0x04, 0xc0, 0x02, 0xc2, + 0x00, 0xba, 0x64, 0x62, + 0x02, 0xcf, 0x00, 0xdc, + 0x24, 0xe4, 0x80, 0x02, + 0x34, 0xd3, 0x2c, 0xc3, + 0x60, 0x70, 0x80, 0x49, + 0xfd, 0xf0, 0x27, 0xc3, + 0x66, 0x60, 0x80, 0x48, + 0x02, 0x48, 0x66, 0x88, + 0x00, 0x48, 0x82, 0x48, + 0x66, 0x88, 0x1b, 0xc3, + 0x60, 0x70, 0x17, 0xc4, + 0x88, 0x98, 0x14, 0xc0, + 0x8c, 0x98, 0x83, 0x18, 0x8e, 0x88, 0x8e, 0x70, 0x8f, 0x49, 0xfe, 0xf1, - 0x08, 0xc3, 0x02, 0xc4, - 0x00, 0xbc, 0x68, 0x0f, - 0x6c, 0xe9, 0x00, 0xdc, - 0x50, 0xe8, 0x30, 0xc1, - 0x36, 0xd3, 0x80, 0x10, - 0x00, 0x00, 0x80, 0xd4, - 0x26, 0xd8, 0x44, 0xc2, - 0x4a, 0x41, 0x94, 0x20, - 0x42, 0xc0, 0x16, 0x00, - 0x00, 0x73, 0x40, 0xc4, - 0x5c, 0x41, 0x8b, 0x41, - 0x0b, 0x18, 0x38, 0xc6, - 0xc0, 0x88, 0xc1, 0x99, - 0x21, 0xe8, 0x35, 0xc0, - 0x00, 0x73, 0xbd, 0x48, - 0x0d, 0x18, 0x30, 0xc6, + 0x62, 0x70, 0x8a, 0x98, + 0x0d, 0xc0, 0x8c, 0x98, + 0x84, 0x18, 0x8e, 0x88, + 0x8e, 0x70, 0x8f, 0x49, + 0xfe, 0xf1, 0x08, 0xc3, + 0x02, 0xc4, 0x00, 0xbc, + 0x68, 0x0f, 0x6c, 0xe9, + 0x00, 0xdc, 0x50, 0xe8, + 0x30, 0xc1, 0x36, 0xd3, + 0x80, 0x10, 0x00, 0x00, + 0x80, 0xd4, 0x26, 0xd8, + 0x44, 0xc2, 0x4a, 0x41, + 0x94, 0x20, 0x42, 0xc0, + 0x16, 0x00, 0x00, 0x73, + 0x40, 0xc4, 0x5c, 0x41, + 0x8b, 0x41, 0x0b, 0x18, + 0x38, 0xc6, 0xc0, 0x88, + 0xc1, 0x99, 0x21, 0xe8, + 0x35, 0xc0, 0x00, 0x73, + 0xbd, 0x48, 0x0d, 0x18, + 0x30, 0xc6, 0xc0, 0x88, + 0xc1, 0x9b, 0x19, 0xe8, + 0x2d, 0xc0, 0x02, 0x73, + 0x35, 0x48, 0x0e, 0x18, + 0x28, 0xc6, 0xc0, 0x88, + 0xc1, 0x9b, 0x11, 0xe8, + 0xdf, 0xc3, 0xdd, 0xc6, + 0x01, 0x03, 0x1e, 0x40, + 0xfe, 0xf1, 0x20, 0xc0, + 0x02, 0x73, 0xb5, 0x48, + 0x0e, 0x18, 0x1b, 0xc6, 0xc0, 0x88, 0xc1, 0x9b, - 0x19, 0xe8, 0x2d, 0xc0, - 0x02, 0x73, 0x35, 0x48, - 0x0e, 0x18, 0x28, 0xc6, - 0xc0, 0x88, 0xc1, 0x9b, - 0x11, 0xe8, 0xdf, 0xc3, - 0xdd, 0xc6, 0x01, 0x03, - 0x1e, 0x40, 0xfe, 0xf1, - 0x20, 0xc0, 0x02, 0x73, - 0xb5, 0x48, 0x0e, 0x18, - 0x1b, 0xc6, 0xc0, 0x88, - 0xc1, 0x9b, 0x04, 0xe8, - 0x02, 0xc6, 0x00, 0xbe, - 0xb6, 0x10, 0x00, 0xb4, - 0x01, 0xb4, 0x02, 0xb4, - 0x03, 0xb4, 0x10, 0xc3, - 0x0e, 0xc2, 0x61, 0x71, - 0x40, 0x99, 0x60, 0x60, - 0x0e, 0x48, 0x42, 0x98, - 0x42, 0x70, 0x8e, 0x49, - 0xfe, 0xf1, 0x03, 0xb0, - 0x02, 0xb0, 0x01, 0xb0, - 0x00, 0xb0, 0x80, 0xff, - 0xc0, 0xd4, 0x8f, 0xcb, - 0xaa, 0xc7, 0x1e, 0x00, - 0x90, 0xc7, 0x1f, 0xfe, - 0x0a, 0x10, 0x0c, 0xf0, - 0x0b, 0x10, 0x0a, 0xf0, - 0x0d, 0x10, 0x08, 0xf0, - 0x0e, 0x10, 0x06, 0xf0, - 0x24, 0x10, 0x04, 0xf0, - 0x02, 0xc7, 0x00, 0xbf, - 0x58, 0x11, 0x02, 0xc7, - 0x00, 0xbf, 0x62, 0x11, - 0xec, 0xc0, 0x02, 0x75, - 0xd5, 0x48, 0x0e, 0x18, - 0xe7, 0xc6, 0xc0, 0x88, - 0xc1, 0x9d, 0xd0, 0xef, - 0xe4, 0xc0, 0x02, 0x75, - 0x55, 0x48, 0x0e, 0x18, - 0xdf, 0xc6, 0xc0, 0x88, - 0xc1, 0x9d, 0xc8, 0xef, - 0x02, 0xc7, 0x00, 0xbf, - 0x8e, 0x11, 0x16, 0xc0, - 0xbb, 0x21, 0xb9, 0x25, - 0x00, 0x71, 0x13, 0xc2, - 0x4a, 0x41, 0x8b, 0x41, - 0x24, 0x18, 0xd0, 0xc6, - 0xc0, 0x88, 0xc1, 0x99, - 0xb9, 0xef, 0x0a, 0xc0, - 0x08, 0x71, 0x28, 0x18, - 0xc9, 0xc6, 0xc0, 0x88, - 0xc1, 0x99, 0xb2, 0xef, - 0x02, 0xc0, 0x00, 0xb8, - 0x3c, 0x11, 0xd8, 0xc7, - 0x83, 0xff, 0x01, 0xb4, + 0x04, 0xe8, 0x02, 0xc6, + 0x00, 0xbe, 0xb6, 0x10, + 0x00, 0xb4, 0x01, 0xb4, 0x02, 0xb4, 0x03, 0xb4, - 0x04, 0xb4, 0x05, 0xb4, - 0x43, 0xc4, 0x44, 0xc0, - 0x47, 0xc1, 0x81, 0x1b, - 0xcd, 0xe8, 0x45, 0xc0, - 0x43, 0xc2, 0x84, 0x1b, - 0xc9, 0xe8, 0x58, 0xc0, - 0x00, 0x1b, 0xc6, 0xe8, - 0x80, 0x65, 0xdb, 0x22, - 0xdd, 0x26, 0x03, 0x15, - 0x12, 0xf1, 0x4d, 0xc0, - 0x36, 0xc1, 0x81, 0x1b, - 0xbd, 0xe8, 0x4a, 0xc0, - 0x31, 0xc1, 0x88, 0x1b, - 0xb9, 0xe8, 0x47, 0xc0, - 0x48, 0xc1, 0x81, 0x1b, - 0xb5, 0xe8, 0x04, 0x00, - 0x45, 0xc1, 0x45, 0xc2, - 0x8f, 0x1b, 0xb0, 0xe8, - 0x24, 0xc0, 0x28, 0xc1, - 0x2a, 0xc2, 0xac, 0xe8, + 0x10, 0xc3, 0x0e, 0xc2, + 0x61, 0x71, 0x40, 0x99, + 0x60, 0x60, 0x0e, 0x48, + 0x42, 0x98, 0x42, 0x70, + 0x8e, 0x49, 0xfe, 0xf1, + 0x03, 0xb0, 0x02, 0xb0, + 0x01, 0xb0, 0x00, 0xb0, + 0x80, 0xff, 0xc0, 0xd4, + 0x8f, 0xcb, 0xaa, 0xc7, + 0x1e, 0x00, 0x90, 0xc7, + 0x1f, 0xfe, 0x0a, 0x10, + 0x0c, 0xf0, 0x0b, 0x10, + 0x0a, 0xf0, 0x0d, 0x10, + 0x08, 0xf0, 0x0e, 0x10, + 0x06, 0xf0, 0x24, 0x10, + 0x04, 0xf0, 0x02, 0xc7, + 0x00, 0xbf, 0x58, 0x11, + 0x02, 0xc7, 0x00, 0xbf, + 0x62, 0x11, 0xec, 0xc0, + 0x02, 0x75, 0xd5, 0x48, + 0x0e, 0x18, 0xe7, 0xc6, + 0xc0, 0x88, 0xc1, 0x9d, + 0xd0, 0xef, 0xe4, 0xc0, + 0x02, 0x75, 0x55, 0x48, + 0x0e, 0x18, 0xdf, 0xc6, + 0xc0, 0x88, 0xc1, 0x9d, + 0xc8, 0xef, 0x02, 0xc7, + 0x00, 0xbf, 0x8e, 0x11, + 0x16, 0xc0, 0xbb, 0x21, + 0xb9, 0x25, 0x00, 0x71, + 0x13, 0xc2, 0x4a, 0x41, + 0x8b, 0x41, 0x24, 0x18, + 0xd0, 0xc6, 0xc0, 0x88, + 0xc1, 0x99, 0xb9, 0xef, + 0x0a, 0xc0, 0x08, 0x71, + 0x28, 0x18, 0xc9, 0xc6, + 0xc0, 0x88, 0xc1, 0x99, + 0xb2, 0xef, 0x02, 0xc0, + 0x00, 0xb8, 0x3c, 0x11, + 0xd8, 0xc7, 0x83, 0xff, + 0x01, 0xb4, 0x02, 0xb4, + 0x03, 0xb4, 0x04, 0xb4, + 0x05, 0xb4, 0x44, 0xc4, + 0x45, 0xc0, 0x48, 0xc1, + 0x81, 0x1b, 0xce, 0xe8, + 0x46, 0xc0, 0x44, 0xc2, + 0x84, 0x1b, 0xca, 0xe8, + 0x59, 0xc0, 0x00, 0x1b, + 0xc7, 0xe8, 0x80, 0x65, + 0xdb, 0x22, 0xdd, 0x26, + 0x03, 0x15, 0x12, 0xf1, + 0x4e, 0xc0, 0x37, 0xc1, + 0x81, 0x1b, 0xbe, 0xe8, + 0x4b, 0xc0, 0x32, 0xc1, + 0x88, 0x1b, 0xba, 0xe8, + 0x48, 0xc0, 0x49, 0xc1, + 0x81, 0x1b, 0xb6, 0xe8, + 0x04, 0x00, 0x46, 0xc1, + 0x46, 0xc2, 0x8f, 0x1b, + 0xb1, 0xe8, 0x25, 0xc0, + 0x29, 0xc1, 0x2b, 0xc2, + 0x8f, 0x1b, 0xac, 0xe8, 0x04, 0x00, 0x3e, 0xc1, 0x27, 0xc2, 0xa8, 0xe8, 0x04, 0x00, 0x2b, 0xc1, @@ -10902,8 +11195,40 @@ static void r8156_patch_code(struct r8152 *tp) 0x80, 0x99, 0x82, 0x9a, 0x86, 0x8b, 0x86, 0x75, 0xdf, 0x49, 0xfe, 0xf1, - 0x80, 0xff, 0x02, 0xc0, - 0x00, 0xb8, 0x00, 0x00}; + 0x80, 0xff, 0x3b, 0xc0, + 0x3b, 0xc1, 0x00, 0x70, + 0x08, 0x40, 0x34, 0xf1, + 0x38, 0xc0, 0x38, 0xc1, + 0x0c, 0x99, 0x00, 0x19, + 0x0e, 0x89, 0x0e, 0x71, + 0x9f, 0x49, 0xfe, 0xf1, + 0x0a, 0x71, 0x9a, 0x48, + 0x0a, 0x99, 0x8f, 0x19, + 0x0e, 0x89, 0x0e, 0x71, + 0x9f, 0x49, 0xfe, 0xf1, + 0x2a, 0xc0, 0x00, 0x71, + 0x90, 0x48, 0x00, 0x99, + 0x27, 0xc0, 0x00, 0x71, + 0x13, 0x48, 0x00, 0x99, + 0x20, 0xc0, 0x20, 0xc1, + 0x0c, 0x99, 0x00, 0x19, + 0x0e, 0x89, 0x0e, 0x71, + 0x9f, 0x49, 0xfe, 0xf1, + 0x0a, 0x71, 0x9b, 0x48, + 0x0a, 0x99, 0x8f, 0x19, + 0x0e, 0x89, 0x0e, 0x71, + 0x9f, 0x49, 0xfe, 0xf1, + 0x12, 0xc0, 0x00, 0x71, + 0x10, 0x48, 0x00, 0x99, + 0x0f, 0xc0, 0x00, 0x71, + 0x93, 0x48, 0x00, 0x99, + 0x06, 0xc0, 0x00, 0x19, + 0x00, 0x99, 0x09, 0xc7, + 0x09, 0xc5, 0x00, 0xbd, + 0x80, 0xd2, 0x86, 0x64, + 0x00, 0xdc, 0x10, 0xe8, + 0xb0, 0xd4, 0x06, 0xd4, + 0xc0, 0xd4, 0x72, 0x14}; static u8 pla_patch11[] = { 0x05, 0xe0, 0x0a, 0xe0, 0x38, 0xe0, 0x3a, 0xe0, @@ -11003,31 +11328,39 @@ static void r8156_patch_code(struct r8152 *tp) 0x10, 0xe0, 0xe0, 0xe8, 0x80, 0x11, 0x02, 0x80, 0x30, 0x10, 0xb4, 0xc0}; + u8 new_ver; - rtl_clear_bp(tp, MCU_TYPE_USB); + rtl_fw_ver_erase(tp); - generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb_patch3_b), - usb_patch3_b, MCU_TYPE_USB); + new_ver = 7; + if (rtl_check_fw_ver_ok(tp, USB_FW_USB_VER, new_ver)) { + rtl_clear_bp(tp, MCU_TYPE_USB); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xa000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x39d4); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x3c98); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x293c); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x1cfe); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x2738); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x21ba); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x4efc); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x4dfe); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x6262); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x0f66); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x1098); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x1148); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x116c); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x10e0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0f6a); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x7fff); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd7, 0x04); + generic_ocp_write(tp, 0xe600, 0xff, + sizeof(usb_patch3_b), usb_patch3_b, + MCU_TYPE_USB); + + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xa000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x39d4); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x099c); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x293c); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x1cfe); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x2738); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x21ba); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x3962); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x51ba); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x6262); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x0f66); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x1098); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x1148); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x116c); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x10e0); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0f6a); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x7fff); + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_USB_VER, + new_ver); + } ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); ocp_data |= FW_IP_RESET_EN; @@ -11036,22 +11369,26 @@ static void r8156_patch_code(struct r8152 *tp) ocp_write_dword(tp, MCU_TYPE_USB, USB_UPHY3_MDCMDIO, 0x4026840e); ocp_write_dword(tp, MCU_TYPE_USB, USB_UPHY3_MDCMDIO, 0x4001acc9); - rtl_clear_bp(tp, MCU_TYPE_PLA); + new_ver = 6; + if (rtl_check_fw_ver_ok(tp, USB_FW_PLA_VER, new_ver)) { + rtl_clear_bp(tp, MCU_TYPE_PLA); - generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch11), - pla_patch11, MCU_TYPE_PLA); + generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch11), + pla_patch11, MCU_TYPE_PLA); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x0bc2); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x03e0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x06b8); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x03ba); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x03b2); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0017); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd6, 0x06); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x0bc2); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x03e0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x06b8); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x03ba); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x03b2); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0017); + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_PLA_VER, + new_ver); + } } else if (tp->version == RTL_VER_12) { static u8 usb_patch4_a[] = { 0x10, 0xe0, 0x38, 0xe0, @@ -11236,31 +11573,39 @@ static void r8156_patch_code(struct r8152 *tp) 0x02, 0xc6, 0x00, 0xbe, 0x00, 0x00, 0x02, 0xc6, 0x00, 0xbe, 0x00, 0x00}; + u8 new_ver; - rtl_clear_bp(tp, MCU_TYPE_USB); + rtl_fw_ver_erase(tp); - generic_ocp_write(tp, 0xe600, 0xff, sizeof(usb_patch4_a), - usb_patch4_a, MCU_TYPE_USB); + new_ver = 2; + if (rtl_check_fw_ver_ok(tp, USB_FW_USB_VER, new_ver)) { + rtl_clear_bp(tp, MCU_TYPE_USB); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xc000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x11e2); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x1268); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x35c0); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x1538); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x2f4e); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x2cd8); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x7c26); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x7c90); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x0000); -// ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); - ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x00df); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd7, 0x02); + generic_ocp_write(tp, 0xe600, 0xff, + sizeof(usb_patch4_a), usb_patch4_a, + MCU_TYPE_USB); + + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xc000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x11e2); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_1, 0x1268); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_2, 0x35c0); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_3, 0x1538); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_4, 0x2f4e); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_5, 0x2cd8); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_6, 0x7c26); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_7, 0x7c90); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0x0000); +// ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_10, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_11, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_12, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_13, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x00df); + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_USB_VER, + new_ver); + } // ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_FIX_EN1); // ocp_data |= FW_IP_RESET_EN; @@ -11269,22 +11614,27 @@ static void r8156_patch_code(struct r8152 *tp) // ocp_write_dword(tp, MCU_TYPE_USB, 0xd480, 0x4026840e); // ocp_write_dword(tp, MCU_TYPE_USB, 0xd480, 0x4001acc9); - rtl_clear_bp(tp, MCU_TYPE_PLA); + new_ver = 2; + if (rtl_check_fw_ver_ok(tp, USB_FW_PLA_VER, new_ver)) { + rtl_clear_bp(tp, MCU_TYPE_PLA); - generic_ocp_write(tp, 0xf800, 0xff, sizeof(pla_patch4_a), - pla_patch4_a, MCU_TYPE_PLA); + generic_ocp_write(tp, 0xf800, 0xff, + sizeof(pla_patch4_a), pla_patch4_a, + MCU_TYPE_PLA); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x03b2); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x058a); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x16c0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0007); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd6, 0x02); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x03b2); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_1, 0x058a); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_2, 0x16c0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_3, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_4, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_5, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x0007); + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_PLA_VER, + new_ver); + } } else if (tp->version == RTL_VER_13 || tp->version == RTL_VER_15) { static u8 usb_patch_13[] = { 0x10, 0xe0, 0x25, 0xe0, @@ -11611,13 +11961,17 @@ static void r8156_patch_code(struct r8152 *tp) 0x02, 0xc0, 0x00, 0xb8, 0x3a, 0x4e, 0x02, 0xc0, 0x00, 0xb8, 0x3a, 0x4e}; + u8 new_ver; - if (ocp_read_byte(tp, MCU_TYPE_USB, 0xcfd7) < 0x04) { + rtl_fw_ver_erase(tp); + + new_ver = 4; + if (rtl_check_fw_ver_ok(tp, USB_FW_USB_VER, new_ver)) { rtl_clear_bp(tp, MCU_TYPE_USB); generic_ocp_write(tp, 0xe600, 0xff, - sizeof(usb_patch_13), - usb_patch_13, MCU_TYPE_USB); + sizeof(usb_patch_13), usb_patch_13, + MCU_TYPE_USB); ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0xc000); ocp_write_word(tp, MCU_TYPE_USB, USB_BP_0, 0x0fba); @@ -11637,15 +11991,17 @@ static void r8156_patch_code(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_USB, USB_BP_14, 0x0000); ocp_write_word(tp, MCU_TYPE_USB, USB_BP_15, 0x0000); ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0x07ff); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd7, 0x04); + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_USB_VER, + new_ver); } - if (ocp_read_byte(tp, MCU_TYPE_USB, 0xcfd6) < 0x06) { + new_ver = 6; + if (rtl_check_fw_ver_ok(tp, USB_FW_PLA_VER, new_ver)) { rtl_clear_bp(tp, MCU_TYPE_PLA); generic_ocp_write(tp, 0xf800, 0xff, - sizeof(pla_patch_13), - pla_patch_13, MCU_TYPE_PLA); + sizeof(pla_patch_13), pla_patch_13, + MCU_TYPE_PLA); ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0x8000); ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_0, 0x374e); @@ -11657,7 +12013,8 @@ static void r8156_patch_code(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_6, 0x0000); ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_7, 0x0000); ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_EN, 0x003f); - ocp_write_byte(tp, MCU_TYPE_USB, 0xcfd6, 0x06); + ocp_write_byte(tp, MCU_TYPE_USB, USB_FW_PLA_VER, + new_ver); } } @@ -12721,6 +13078,16 @@ static void rtl_ram_code_speed_up(struct r8152 *tp, bool wait) if (sram_read(tp, SRAM_GPHY_FW_VER) < 0x0021) { data = ram13; len = sizeof(ram13); + + if (r8156b_flash_used(tp)) { + u32 ocp_data; + + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, + USB_GPHY_CTRL); + ocp_data |= BYPASS_FLASH; + ocp_write_word(tp, MCU_TYPE_USB, USB_GPHY_CTRL, + ocp_data); + } } } @@ -16889,6 +17256,11 @@ static void r8156_hw_phy_cfg(struct r8152 *tp) ((swap_a & 0x1f) << 8) | ((swap_a >> 8) & 0x1f)); } + + /* Notify the MAC when the speed is changed to force mode. */ + data = ocp_reg_read(tp, OCP_INTR_EN); + data |= INTR_SPEED_FORCE; + ocp_reg_write(tp, OCP_INTR_EN, data); break; default: break; @@ -17286,6 +17658,11 @@ static void r8156b_hw_phy_cfg(struct r8152 *tp) break; } + /* Notify the MAC when the speed is changed to force mode. */ + data = ocp_reg_read(tp, OCP_INTR_EN); + data |= INTR_SPEED_FORCE; + ocp_reg_write(tp, OCP_INTR_EN, data); + if (rtl_phy_patch_request(tp, true, true)) return; @@ -17551,7 +17928,7 @@ static void r8156_init(struct r8152 *tp) // break; // case 0x8000: // tp->dash_mode = 0; - r8156_mac_clk_spd(tp, true); + r8156_mac_clk_spd(tp, false); // break; // default: // netif_warn(tp, drv, tp->netdev, "Invalid type %x\n", ocp_data); @@ -17561,6 +17938,18 @@ static void r8156_init(struct r8152 *tp) r8153b_mcu_spdown_en(tp, false); + /* enable fc timer and set timer to 1s. */ + ocp_write_word(tp, MCU_TYPE_USB, USB_FC_TIMER, + CTRL_TIMER_EN | (1000 / 8)); + + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_TASK); + ocp_data |= FC_PATCH_TASK; + ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); + + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_FW_CTRL); + ocp_data |= FLOW_CTRL_PATCH_OPT; + ocp_write_word(tp, MCU_TYPE_USB, USB_FW_CTRL, ocp_data); + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); if (rtl8152_get_speed(tp) & LINK_STATUS) ocp_data |= CUR_LINK_OK; @@ -17697,7 +18086,7 @@ static void r8156b_init(struct r8152 *tp) ocp_data |= FC_PATCH_TASK; ocp_write_word(tp, MCU_TYPE_USB, USB_FW_TASK, ocp_data); - r8156_mac_clk_spd(tp, true); + r8156_mac_clk_spd(tp, false); r8153b_mcu_spdown_en(tp, false); ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS); @@ -17819,6 +18208,7 @@ static bool rtl_check_vendor_ok(struct usb_interface *intf) return true; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) static bool rtl_vendor_mode(struct usb_interface *intf) { struct usb_host_interface *alt = intf->cur_altsetting; @@ -17859,6 +18249,7 @@ static bool rtl_vendor_mode(struct usb_interface *intf) return false; } +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) */ static int rtl8152_pre_reset(struct usb_interface *intf) { @@ -18229,8 +18620,8 @@ static void rtl8152_get_drvinfo(struct net_device *netdev, { struct r8152 *tp = netdev_priv(netdev); - strlcpy(info->driver, MODULENAME, sizeof(info->driver)); - strlcpy(info->version, DRIVER_VERSION, sizeof(info->version)); + strscpy(info->driver, MODULENAME, sizeof(info->driver)); + strscpy(info->version, DRIVER_VERSION, sizeof(info->version)); usb_make_path(tp->udev, info->bus_info, sizeof(info->bus_info)); } @@ -19669,7 +20060,7 @@ static int rtl_ops_init(struct r8152 *tp) case RTL_VER_10: ops->init = r8156_init; ops->enable = rtl8156_enable; - ops->disable = rtl8153_disable; + ops->disable = rtl8156_disable; ops->up = rtl8156_up; ops->down = rtl8156_down; ops->unload = rtl8153_unload; @@ -19738,9 +20129,8 @@ static int rtl_ops_init(struct r8152 *tp) return ret; } -u8 rtl8152_get_version(struct usb_interface *intf) +static u8 __rtl_get_hw_ver(struct usb_device *udev) { - struct usb_device *udev = interface_to_usbdev(intf); u32 ocp_data = 0; __le32 *tmp; u8 version; @@ -19809,10 +20199,19 @@ u8 rtl8152_get_version(struct usb_interface *intf) break; default: version = RTL_VER_UNKNOWN; - dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data); + dev_info(&udev->dev, "Unknown version 0x%04x\n", ocp_data); break; } + return version; +} + +u8 rtl8152_get_version(struct usb_interface *intf) +{ + u8 version; + + version = __rtl_get_hw_ver(interface_to_usbdev(intf)); + dev_dbg(&intf->dev, "Detected version 0x%04x\n", version); return version; @@ -20450,7 +20849,7 @@ static ssize_t sg_en_store(struct device *dev, struct device_attribute *attr, if (!strncmp(buf, "enable", 6) && usb_device_no_sg_constraint(tp->udev)) { tp->sg_use = true; - tso_size = GSO_MAX_SIZE; + tso_size = TSO_LEGACY_MAX_SIZE; } else if (!strncmp(buf, "disable", 7)) { tp->sg_use = false; tso_size = RTL_LIMITED_TSO_SIZE; @@ -20459,7 +20858,7 @@ static ssize_t sg_en_store(struct device *dev, struct device_attribute *attr, } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) - netif_set_gso_max_size(netdev, tso_size); + netif_set_tso_max_size(netdev, tso_size); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */ return count; @@ -20480,16 +20879,36 @@ static struct attribute_group rtk_adv_grp = { .attrs = rtk_adv_attrs, }; +static bool rtl8152_supports_lenovo_macpassthru(struct usb_device *udev) +{ + int parent_vendor_id = le16_to_cpu(udev->parent->descriptor.idVendor); + int product_id = le16_to_cpu(udev->descriptor.idProduct); + int vendor_id = le16_to_cpu(udev->descriptor.idVendor); + + if (vendor_id == VENDOR_ID_LENOVO) { + switch (product_id) { + case DEVICE_ID_LENOVO_USB_C_TRAVEL_HUB: + case DEVICE_ID_THINKPAD_ONELINK_PLUS_DOCK: + case DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2: + case DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2: + case DEVICE_ID_THINKPAD_USB_C_DOCK_GEN3: + case DEVICE_ID_THINKPAD_USB_C_DONGLE: + return 1; + } + } else if (vendor_id == VENDOR_ID_REALTEK && parent_vendor_id == VENDOR_ID_LENOVO) { + switch (product_id) { + case 0x8153: + return 1; + } + } + return 0; +} + static void rtl_get_mapt_ver(struct r8152 *tp) { struct usb_device *udev = tp->udev; u32 ocp_data; - if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO) { - tp->lenovo_macpassthru = 1; - return; - } - /* test for -AD variant of RTL8153 */ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); if ((ocp_data & AD_MASK) == 0x1000) { @@ -20506,26 +20925,38 @@ static void rtl_get_mapt_ver(struct r8152 *tp) if ((ocp_data & BND_MASK) || (ocp_data & BD_MASK)) { tp->dell_macpassthru = 1; return; - } else if (tp->version == RTL_VER_09 && (ocp_data & BL_MASK)) { - tp->lenovo_macpassthru = 1; - return; } + + tp->lenovo_macpassthru = rtl8152_supports_lenovo_macpassthru(udev); } static int rtl8152_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); - u8 version = rtl8152_get_version(intf); struct r8152 *tp; struct net_device *netdev; + u8 version; int ret; +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) + version = rtl8152_get_version(intf); if (version == RTL_VER_UNKNOWN) return -ENODEV; if (!rtl_vendor_mode(intf)) return -ENODEV; +#else + if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) + return -ENODEV; + + if (!rtl_check_vendor_ok(intf)) + return -ENODEV; + + version = rtl8152_get_version(intf); + if (version == RTL_VER_UNKNOWN) + return -ENODEV; +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) */ usb_reset_device(udev); netdev = alloc_etherdev(sizeof(struct r8152)); @@ -20622,7 +21053,7 @@ static int rtl8152_probe(struct usb_interface *intf, netdev->ethtool_ops = &ops; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) if (!tp->sg_use) - netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE); + netif_set_tso_max_size(netdev, RTL_LIMITED_TSO_SIZE); #else netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) */ @@ -20700,10 +21131,8 @@ static int rtl8152_probe(struct usb_interface *intf, usb_set_intfdata(intf, tp); - if (tp->support_2500full) - netif_napi_add(netdev, &tp->napi, r8152_poll, 256); - else - netif_napi_add(netdev, &tp->napi, r8152_poll, 64); + netif_napi_add_weight(netdev, &tp->napi, r8152_poll, + tp->support_2500full ? 256 : 64); ret = register_netdev(netdev); if (ret != 0) { @@ -20802,6 +21231,7 @@ static const struct usb_device_id rtl8152_table[] = { REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab), REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6), REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927), + REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0c5e), /* Samsung */ REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101), @@ -20825,18 +21255,21 @@ static const struct usb_device_id rtl8152_table[] = { REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa359), REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387), - /* TP-LINK */ - REALTEK_USB_DEVICE(VENDOR_ID_TPLINK, 0x0601), - - /* Nvidia */ - REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff), - /* LINKSYS */ REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041), + /* Nvidia */ + REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff), + + /* TP-LINK */ + REALTEK_USB_DEVICE(VENDOR_ID_TPLINK, 0x0601), + /* Getac */ REALTEK_USB_DEVICE(0x2baf, 0x0012), + /* ASUSTek */ + REALTEK_USB_DEVICE(0x0b05, 0x1976), + {} }; @@ -20858,7 +21291,71 @@ static struct usb_driver rtl8152_driver = { #endif }; +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) module_usb_driver(rtl8152_driver); +#else +static int rtl8152_cfgselector_probe(struct usb_device *udev) +{ + struct usb_host_config *c; + int i, num_configs; + + /* Switch the device to vendor mode, if and only if the vendor mode + * driver supports it. + */ + if (__rtl_get_hw_ver(udev) == RTL_VER_UNKNOWN) + return 0; + + /* The vendor mode is not always config #1, so to find it out. */ + c = udev->config; + num_configs = udev->descriptor.bNumConfigurations; + for (i = 0; i < num_configs; (i++, c++)) { + struct usb_interface_descriptor *desc = NULL; + + if (!c->desc.bNumInterfaces) + continue; + desc = &c->intf_cache[0]->altsetting->desc; + if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) + break; + } + + if (i == num_configs) + return -ENODEV; + + if (usb_set_configuration(udev, c->desc.bConfigurationValue)) { + dev_err(&udev->dev, "Failed to set configuration %d\n", + c->desc.bConfigurationValue); + return -ENODEV; + } + return 0; +} + +static struct usb_device_driver rtl8152_cfgselector_driver = { + .name = MODULENAME "-cfgselector", + .probe = rtl8152_cfgselector_probe, + .id_table = rtl8152_table, + .generic_subclass = 1, + .supports_autosuspend = 1, +}; + +static int __init rtl8152_driver_init(void) +{ + int ret; + + ret = usb_register_device_driver(&rtl8152_cfgselector_driver, THIS_MODULE); + if (ret) + return ret; + return usb_register(&rtl8152_driver); +} + +static void __exit rtl8152_driver_exit(void) +{ + usb_deregister(&rtl8152_driver); + usb_deregister_device_driver(&rtl8152_cfgselector_driver); +} + +module_init(rtl8152_driver_init); +module_exit(rtl8152_driver_exit); +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,7,0) */ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC);