diff options
| -rw-r--r-- | drivers/net/usb/r8152.c | 95 | 
1 files changed, 93 insertions, 2 deletions
| diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index a90a7eb91f1c..aa1d5b2e9c30 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
| @@ -60,7 +60,7 @@ | |||
| 60 | #define PLA_TCR0 0xe610 | 60 | #define PLA_TCR0 0xe610 | 
| 61 | #define PLA_TCR1 0xe612 | 61 | #define PLA_TCR1 0xe612 | 
| 62 | #define PLA_TXFIFO_CTRL 0xe618 | 62 | #define PLA_TXFIFO_CTRL 0xe618 | 
| 63 | #define PLA_RSTTELLY 0xe800 | 63 | #define PLA_RSTTALLY 0xe800 | 
| 64 | #define PLA_CR 0xe813 | 64 | #define PLA_CR 0xe813 | 
| 65 | #define PLA_CRWECR 0xe81c | 65 | #define PLA_CRWECR 0xe81c | 
| 66 | #define PLA_CONFIG12 0xe81e /* CONFIG1, CONFIG2 */ | 66 | #define PLA_CONFIG12 0xe81e /* CONFIG1, CONFIG2 */ | 
| @@ -72,7 +72,7 @@ | |||
| 72 | #define PLA_MISC_0 0xe858 | 72 | #define PLA_MISC_0 0xe858 | 
| 73 | #define PLA_MISC_1 0xe85a | 73 | #define PLA_MISC_1 0xe85a | 
| 74 | #define PLA_OCP_GPHY_BASE 0xe86c | 74 | #define PLA_OCP_GPHY_BASE 0xe86c | 
| 75 | #define PLA_TELLYCNT 0xe890 | 75 | #define PLA_TALLYCNT 0xe890 | 
| 76 | #define PLA_SFF_STS_7 0xe8de | 76 | #define PLA_SFF_STS_7 0xe8de | 
| 77 | #define PLA_PHYSTATUS 0xe908 | 77 | #define PLA_PHYSTATUS 0xe908 | 
| 78 | #define PLA_BP_BA 0xfc26 | 78 | #define PLA_BP_BA 0xfc26 | 
| @@ -180,6 +180,9 @@ | |||
| 180 | /* PLA_TCR1 */ | 180 | /* PLA_TCR1 */ | 
| 181 | #define VERSION_MASK 0x7cf0 | 181 | #define VERSION_MASK 0x7cf0 | 
| 182 | 182 | ||
| 183 | /* PLA_RSTTALLY */ | ||
| 184 | #define TALLY_RESET 0x0001 | ||
| 185 | |||
| 183 | /* PLA_CR */ | 186 | /* PLA_CR */ | 
| 184 | #define CR_RST 0x10 | 187 | #define CR_RST 0x10 | 
| 185 | #define CR_RE 0x08 | 188 | #define CR_RE 0x08 | 
| @@ -465,6 +468,22 @@ enum rtl8152_flags { | |||
| 465 | #define REALTEK_USB_DEVICE(vend, prod) \ | 468 | #define REALTEK_USB_DEVICE(vend, prod) \ | 
| 466 | USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC) | 469 | USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC) | 
| 467 | 470 | ||
| 471 | struct tally_counter { | ||
| 472 | __le64 tx_packets; | ||
| 473 | __le64 rx_packets; | ||
| 474 | __le64 tx_errors; | ||
| 475 | __le32 rx_errors; | ||
| 476 | __le16 rx_missed; | ||
| 477 | __le16 align_errors; | ||
| 478 | __le32 tx_one_collision; | ||
| 479 | __le32 tx_multi_collision; | ||
| 480 | __le64 rx_unicast; | ||
| 481 | __le64 rx_broadcast; | ||
| 482 | __le32 rx_multicast; | ||
| 483 | __le16 tx_aborted; | ||
| 484 | __le16 tx_underun; | ||
| 485 | }; | ||
| 486 | |||
| 468 | struct rx_desc { | 487 | struct rx_desc { | 
| 469 | __le32 opts1; | 488 | __le32 opts1; | 
| 470 | #define RX_LEN_MASK 0x7fff | 489 | #define RX_LEN_MASK 0x7fff | 
| @@ -2872,6 +2891,15 @@ static void r8152b_enable_fc(struct r8152 *tp) | |||
| 2872 | r8152_mdio_write(tp, MII_ADVERTISE, anar); | 2891 | r8152_mdio_write(tp, MII_ADVERTISE, anar); | 
| 2873 | } | 2892 | } | 
| 2874 | 2893 | ||
| 2894 | static void rtl_tally_reset(struct r8152 *tp) | ||
| 2895 | { | ||
| 2896 | u32 ocp_data; | ||
| 2897 | |||
| 2898 | ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY); | ||
| 2899 | ocp_data |= TALLY_RESET; | ||
| 2900 | ocp_write_word(tp, MCU_TYPE_PLA, PLA_RSTTALLY, ocp_data); | ||
| 2901 | } | ||
| 2902 | |||
| 2875 | static void r8152b_init(struct r8152 *tp) | 2903 | static void r8152b_init(struct r8152 *tp) | 
| 2876 | { | 2904 | { | 
| 2877 | u32 ocp_data; | 2905 | u32 ocp_data; | 
| @@ -2898,6 +2926,7 @@ static void r8152b_init(struct r8152 *tp) | |||
| 2898 | r8152b_enable_eee(tp); | 2926 | r8152b_enable_eee(tp); | 
| 2899 | r8152b_enable_aldps(tp); | 2927 | r8152b_enable_aldps(tp); | 
| 2900 | r8152b_enable_fc(tp); | 2928 | r8152b_enable_fc(tp); | 
| 2929 | rtl_tally_reset(tp); | ||
| 2901 | 2930 | ||
| 2902 | /* enable rx aggregation */ | 2931 | /* enable rx aggregation */ | 
| 2903 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); | 2932 | ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); | 
| @@ -2965,6 +2994,7 @@ static void r8153_init(struct r8152 *tp) | |||
| 2965 | r8153_enable_eee(tp); | 2994 | r8153_enable_eee(tp); | 
| 2966 | r8153_enable_aldps(tp); | 2995 | r8153_enable_aldps(tp); | 
| 2967 | r8152b_enable_fc(tp); | 2996 | r8152b_enable_fc(tp); | 
| 2997 | rtl_tally_reset(tp); | ||
| 2968 | } | 2998 | } | 
| 2969 | 2999 | ||
| 2970 | static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) | 3000 | static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) | 
| @@ -3105,6 +3135,64 @@ out: | |||
| 3105 | return ret; | 3135 | return ret; | 
| 3106 | } | 3136 | } | 
| 3107 | 3137 | ||
| 3138 | static const char rtl8152_gstrings[][ETH_GSTRING_LEN] = { | ||
| 3139 | "tx_packets", | ||
| 3140 | "rx_packets", | ||
| 3141 | "tx_errors", | ||
| 3142 | "rx_errors", | ||
| 3143 | "rx_missed", | ||
| 3144 | "align_errors", | ||
| 3145 | "tx_single_collisions", | ||
| 3146 | "tx_multi_collisions", | ||
| 3147 | "rx_unicast", | ||
| 3148 | "rx_broadcast", | ||
| 3149 | "rx_multicast", | ||
| 3150 | "tx_aborted", | ||
| 3151 | "tx_underrun", | ||
| 3152 | }; | ||
| 3153 | |||
| 3154 | static int rtl8152_get_sset_count(struct net_device *dev, int sset) | ||
| 3155 | { | ||
| 3156 | switch (sset) { | ||
| 3157 | case ETH_SS_STATS: | ||
| 3158 | return ARRAY_SIZE(rtl8152_gstrings); | ||
| 3159 | default: | ||
| 3160 | return -EOPNOTSUPP; | ||
| 3161 | } | ||
| 3162 | } | ||
| 3163 | |||
| 3164 | static void rtl8152_get_ethtool_stats(struct net_device *dev, | ||
| 3165 | struct ethtool_stats *stats, u64 *data) | ||
| 3166 | { | ||
| 3167 | struct r8152 *tp = netdev_priv(dev); | ||
| 3168 | struct tally_counter tally; | ||
| 3169 | |||
| 3170 | generic_ocp_read(tp, PLA_TALLYCNT, sizeof(tally), &tally, MCU_TYPE_PLA); | ||
| 3171 | |||
| 3172 | data[0] = le64_to_cpu(tally.tx_packets); | ||
| 3173 | data[1] = le64_to_cpu(tally.rx_packets); | ||
| 3174 | data[2] = le64_to_cpu(tally.tx_errors); | ||
| 3175 | data[3] = le32_to_cpu(tally.rx_errors); | ||
| 3176 | data[4] = le16_to_cpu(tally.rx_missed); | ||
| 3177 | data[5] = le16_to_cpu(tally.align_errors); | ||
| 3178 | data[6] = le32_to_cpu(tally.tx_one_collision); | ||
| 3179 | data[7] = le32_to_cpu(tally.tx_multi_collision); | ||
| 3180 | data[8] = le64_to_cpu(tally.rx_unicast); | ||
| 3181 | data[9] = le64_to_cpu(tally.rx_broadcast); | ||
| 3182 | data[10] = le32_to_cpu(tally.rx_multicast); | ||
| 3183 | data[11] = le16_to_cpu(tally.tx_aborted); | ||
| 3184 | data[12] = le16_to_cpu(tally.tx_underun); | ||
| 3185 | } | ||
| 3186 | |||
| 3187 | static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data) | ||
| 3188 | { | ||
| 3189 | switch (stringset) { | ||
| 3190 | case ETH_SS_STATS: | ||
| 3191 | memcpy(data, *rtl8152_gstrings, sizeof(rtl8152_gstrings)); | ||
| 3192 | break; | ||
| 3193 | } | ||
| 3194 | } | ||
| 3195 | |||
| 3108 | static struct ethtool_ops ops = { | 3196 | static struct ethtool_ops ops = { | 
| 3109 | .get_drvinfo = rtl8152_get_drvinfo, | 3197 | .get_drvinfo = rtl8152_get_drvinfo, | 
| 3110 | .get_settings = rtl8152_get_settings, | 3198 | .get_settings = rtl8152_get_settings, | 
| @@ -3114,6 +3202,9 @@ static struct ethtool_ops ops = { | |||
| 3114 | .set_msglevel = rtl8152_set_msglevel, | 3202 | .set_msglevel = rtl8152_set_msglevel, | 
| 3115 | .get_wol = rtl8152_get_wol, | 3203 | .get_wol = rtl8152_get_wol, | 
| 3116 | .set_wol = rtl8152_set_wol, | 3204 | .set_wol = rtl8152_set_wol, | 
| 3205 | .get_strings = rtl8152_get_strings, | ||
| 3206 | .get_sset_count = rtl8152_get_sset_count, | ||
| 3207 | .get_ethtool_stats = rtl8152_get_ethtool_stats, | ||
| 3117 | }; | 3208 | }; | 
| 3118 | 3209 | ||
| 3119 | static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) | 3210 | static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) | 
