aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/usb/lan78xx.c252
1 files changed, 239 insertions, 13 deletions
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 705c180163c5..f20890ee03f3 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -36,7 +36,7 @@
36#define DRIVER_AUTHOR "WOOJUNG HUH <woojung.huh@microchip.com>" 36#define DRIVER_AUTHOR "WOOJUNG HUH <woojung.huh@microchip.com>"
37#define DRIVER_DESC "LAN78XX USB 3.0 Gigabit Ethernet Devices" 37#define DRIVER_DESC "LAN78XX USB 3.0 Gigabit Ethernet Devices"
38#define DRIVER_NAME "lan78xx" 38#define DRIVER_NAME "lan78xx"
39#define DRIVER_VERSION "1.0.3" 39#define DRIVER_VERSION "1.0.4"
40 40
41#define TX_TIMEOUT_JIFFIES (5 * HZ) 41#define TX_TIMEOUT_JIFFIES (5 * HZ)
42#define THROTTLE_JIFFIES (HZ / 8) 42#define THROTTLE_JIFFIES (HZ / 8)
@@ -86,6 +86,9 @@
86/* default autosuspend delay (mSec)*/ 86/* default autosuspend delay (mSec)*/
87#define DEFAULT_AUTOSUSPEND_DELAY (10 * 1000) 87#define DEFAULT_AUTOSUSPEND_DELAY (10 * 1000)
88 88
89/* statistic update interval (mSec) */
90#define STAT_UPDATE_TIMER (1 * 1000)
91
89static const char lan78xx_gstrings[][ETH_GSTRING_LEN] = { 92static const char lan78xx_gstrings[][ETH_GSTRING_LEN] = {
90 "RX FCS Errors", 93 "RX FCS Errors",
91 "RX Alignment Errors", 94 "RX Alignment Errors",
@@ -186,6 +189,56 @@ struct lan78xx_statstage {
186 u32 eee_tx_lpi_time; 189 u32 eee_tx_lpi_time;
187}; 190};
188 191
192struct lan78xx_statstage64 {
193 u64 rx_fcs_errors;
194 u64 rx_alignment_errors;
195 u64 rx_fragment_errors;
196 u64 rx_jabber_errors;
197 u64 rx_undersize_frame_errors;
198 u64 rx_oversize_frame_errors;
199 u64 rx_dropped_frames;
200 u64 rx_unicast_byte_count;
201 u64 rx_broadcast_byte_count;
202 u64 rx_multicast_byte_count;
203 u64 rx_unicast_frames;
204 u64 rx_broadcast_frames;
205 u64 rx_multicast_frames;
206 u64 rx_pause_frames;
207 u64 rx_64_byte_frames;
208 u64 rx_65_127_byte_frames;
209 u64 rx_128_255_byte_frames;
210 u64 rx_256_511_bytes_frames;
211 u64 rx_512_1023_byte_frames;
212 u64 rx_1024_1518_byte_frames;
213 u64 rx_greater_1518_byte_frames;
214 u64 eee_rx_lpi_transitions;
215 u64 eee_rx_lpi_time;
216 u64 tx_fcs_errors;
217 u64 tx_excess_deferral_errors;
218 u64 tx_carrier_errors;
219 u64 tx_bad_byte_count;
220 u64 tx_single_collisions;
221 u64 tx_multiple_collisions;
222 u64 tx_excessive_collision;
223 u64 tx_late_collisions;
224 u64 tx_unicast_byte_count;
225 u64 tx_broadcast_byte_count;
226 u64 tx_multicast_byte_count;
227 u64 tx_unicast_frames;
228 u64 tx_broadcast_frames;
229 u64 tx_multicast_frames;
230 u64 tx_pause_frames;
231 u64 tx_64_byte_frames;
232 u64 tx_65_127_byte_frames;
233 u64 tx_128_255_byte_frames;
234 u64 tx_256_511_bytes_frames;
235 u64 tx_512_1023_byte_frames;
236 u64 tx_1024_1518_byte_frames;
237 u64 tx_greater_1518_byte_frames;
238 u64 eee_tx_lpi_transitions;
239 u64 eee_tx_lpi_time;
240};
241
189struct lan78xx_net; 242struct lan78xx_net;
190 243
191struct lan78xx_priv { 244struct lan78xx_priv {
@@ -232,6 +285,15 @@ struct usb_context {
232#define EVENT_DEV_WAKING 6 285#define EVENT_DEV_WAKING 6
233#define EVENT_DEV_ASLEEP 7 286#define EVENT_DEV_ASLEEP 7
234#define EVENT_DEV_OPEN 8 287#define EVENT_DEV_OPEN 8
288#define EVENT_STAT_UPDATE 9
289
290struct statstage {
291 struct mutex access_lock; /* for stats access */
292 struct lan78xx_statstage saved;
293 struct lan78xx_statstage rollover_count;
294 struct lan78xx_statstage rollover_max;
295 struct lan78xx_statstage64 curr_stat;
296};
235 297
236struct lan78xx_net { 298struct lan78xx_net {
237 struct net_device *net; 299 struct net_device *net;
@@ -272,6 +334,7 @@ struct lan78xx_net {
272 334
273 unsigned maxpacket; 335 unsigned maxpacket;
274 struct timer_list delay; 336 struct timer_list delay;
337 struct timer_list stat_monitor;
275 338
276 unsigned long data[5]; 339 unsigned long data[5];
277 340
@@ -284,6 +347,9 @@ struct lan78xx_net {
284 347
285 int fc_autoneg; 348 int fc_autoneg;
286 u8 fc_request_control; 349 u8 fc_request_control;
350
351 int delta;
352 struct statstage stats;
287}; 353};
288 354
289/* use ethtool to change the level for any given device */ 355/* use ethtool to change the level for any given device */
@@ -382,6 +448,93 @@ static int lan78xx_read_stats(struct lan78xx_net *dev,
382 return ret; 448 return ret;
383} 449}
384 450
451#define check_counter_rollover(struct1, dev_stats, member) { \
452 if (struct1->member < dev_stats.saved.member) \
453 dev_stats.rollover_count.member++; \
454 }
455
456static void lan78xx_check_stat_rollover(struct lan78xx_net *dev,
457 struct lan78xx_statstage *stats)
458{
459 check_counter_rollover(stats, dev->stats, rx_fcs_errors);
460 check_counter_rollover(stats, dev->stats, rx_alignment_errors);
461 check_counter_rollover(stats, dev->stats, rx_fragment_errors);
462 check_counter_rollover(stats, dev->stats, rx_jabber_errors);
463 check_counter_rollover(stats, dev->stats, rx_undersize_frame_errors);
464 check_counter_rollover(stats, dev->stats, rx_oversize_frame_errors);
465 check_counter_rollover(stats, dev->stats, rx_dropped_frames);
466 check_counter_rollover(stats, dev->stats, rx_unicast_byte_count);
467 check_counter_rollover(stats, dev->stats, rx_broadcast_byte_count);
468 check_counter_rollover(stats, dev->stats, rx_multicast_byte_count);
469 check_counter_rollover(stats, dev->stats, rx_unicast_frames);
470 check_counter_rollover(stats, dev->stats, rx_broadcast_frames);
471 check_counter_rollover(stats, dev->stats, rx_multicast_frames);
472 check_counter_rollover(stats, dev->stats, rx_pause_frames);
473 check_counter_rollover(stats, dev->stats, rx_64_byte_frames);
474 check_counter_rollover(stats, dev->stats, rx_65_127_byte_frames);
475 check_counter_rollover(stats, dev->stats, rx_128_255_byte_frames);
476 check_counter_rollover(stats, dev->stats, rx_256_511_bytes_frames);
477 check_counter_rollover(stats, dev->stats, rx_512_1023_byte_frames);
478 check_counter_rollover(stats, dev->stats, rx_1024_1518_byte_frames);
479 check_counter_rollover(stats, dev->stats, rx_greater_1518_byte_frames);
480 check_counter_rollover(stats, dev->stats, eee_rx_lpi_transitions);
481 check_counter_rollover(stats, dev->stats, eee_rx_lpi_time);
482 check_counter_rollover(stats, dev->stats, tx_fcs_errors);
483 check_counter_rollover(stats, dev->stats, tx_excess_deferral_errors);
484 check_counter_rollover(stats, dev->stats, tx_carrier_errors);
485 check_counter_rollover(stats, dev->stats, tx_bad_byte_count);
486 check_counter_rollover(stats, dev->stats, tx_single_collisions);
487 check_counter_rollover(stats, dev->stats, tx_multiple_collisions);
488 check_counter_rollover(stats, dev->stats, tx_excessive_collision);
489 check_counter_rollover(stats, dev->stats, tx_late_collisions);
490 check_counter_rollover(stats, dev->stats, tx_unicast_byte_count);
491 check_counter_rollover(stats, dev->stats, tx_broadcast_byte_count);
492 check_counter_rollover(stats, dev->stats, tx_multicast_byte_count);
493 check_counter_rollover(stats, dev->stats, tx_unicast_frames);
494 check_counter_rollover(stats, dev->stats, tx_broadcast_frames);
495 check_counter_rollover(stats, dev->stats, tx_multicast_frames);
496 check_counter_rollover(stats, dev->stats, tx_pause_frames);
497 check_counter_rollover(stats, dev->stats, tx_64_byte_frames);
498 check_counter_rollover(stats, dev->stats, tx_65_127_byte_frames);
499 check_counter_rollover(stats, dev->stats, tx_128_255_byte_frames);
500 check_counter_rollover(stats, dev->stats, tx_256_511_bytes_frames);
501 check_counter_rollover(stats, dev->stats, tx_512_1023_byte_frames);
502 check_counter_rollover(stats, dev->stats, tx_1024_1518_byte_frames);
503 check_counter_rollover(stats, dev->stats, tx_greater_1518_byte_frames);
504 check_counter_rollover(stats, dev->stats, eee_tx_lpi_transitions);
505 check_counter_rollover(stats, dev->stats, eee_tx_lpi_time);
506
507 memcpy(&dev->stats.saved, stats, sizeof(struct lan78xx_statstage));
508}
509
510static void lan78xx_update_stats(struct lan78xx_net *dev)
511{
512 u32 *p, *count, *max;
513 u64 *data;
514 int i;
515 struct lan78xx_statstage lan78xx_stats;
516
517 if (usb_autopm_get_interface(dev->intf) < 0)
518 return;
519
520 p = (u32 *)&lan78xx_stats;
521 count = (u32 *)&dev->stats.rollover_count;
522 max = (u32 *)&dev->stats.rollover_max;
523 data = (u64 *)&dev->stats.curr_stat;
524
525 mutex_lock(&dev->stats.access_lock);
526
527 if (lan78xx_read_stats(dev, &lan78xx_stats) > 0)
528 lan78xx_check_stat_rollover(dev, &lan78xx_stats);
529
530 for (i = 0; i < (sizeof(lan78xx_stats) / (sizeof(u32))); i++)
531 data[i] = (u64)p[i] + ((u64)count[i] * ((u64)max[i] + 1));
532
533 mutex_unlock(&dev->stats.access_lock);
534
535 usb_autopm_put_interface(dev->intf);
536}
537
385/* Loop until the read is completed with timeout called with phy_mutex held */ 538/* Loop until the read is completed with timeout called with phy_mutex held */
386static int lan78xx_phy_wait_not_busy(struct lan78xx_net *dev) 539static int lan78xx_phy_wait_not_busy(struct lan78xx_net *dev)
387{ 540{
@@ -967,6 +1120,8 @@ static int lan78xx_link_reset(struct lan78xx_net *dev)
967 return -EIO; 1120 return -EIO;
968 1121
969 phy_mac_interrupt(phydev, 0); 1122 phy_mac_interrupt(phydev, 0);
1123
1124 del_timer(&dev->stat_monitor);
970 } else if (phydev->link && !dev->link_on) { 1125 } else if (phydev->link && !dev->link_on) {
971 dev->link_on = true; 1126 dev->link_on = true;
972 1127
@@ -1007,6 +1162,12 @@ static int lan78xx_link_reset(struct lan78xx_net *dev)
1007 1162
1008 ret = lan78xx_update_flowcontrol(dev, ecmd.duplex, ladv, radv); 1163 ret = lan78xx_update_flowcontrol(dev, ecmd.duplex, ladv, radv);
1009 phy_mac_interrupt(phydev, 1); 1164 phy_mac_interrupt(phydev, 1);
1165
1166 if (!timer_pending(&dev->stat_monitor)) {
1167 dev->delta = 1;
1168 mod_timer(&dev->stat_monitor,
1169 jiffies + STAT_UPDATE_TIMER);
1170 }
1010 } 1171 }
1011 1172
1012 return ret; 1173 return ret;
@@ -1099,20 +1260,12 @@ static void lan78xx_get_stats(struct net_device *netdev,
1099 struct ethtool_stats *stats, u64 *data) 1260 struct ethtool_stats *stats, u64 *data)
1100{ 1261{
1101 struct lan78xx_net *dev = netdev_priv(netdev); 1262 struct lan78xx_net *dev = netdev_priv(netdev);
1102 struct lan78xx_statstage lan78xx_stat;
1103 u32 *p;
1104 int i;
1105 1263
1106 if (usb_autopm_get_interface(dev->intf) < 0) 1264 lan78xx_update_stats(dev);
1107 return;
1108 1265
1109 if (lan78xx_read_stats(dev, &lan78xx_stat) > 0) { 1266 mutex_lock(&dev->stats.access_lock);
1110 p = (u32 *)&lan78xx_stat; 1267 memcpy(data, &dev->stats.curr_stat, sizeof(dev->stats.curr_stat));
1111 for (i = 0; i < (sizeof(lan78xx_stat) / (sizeof(u32))); i++) 1268 mutex_unlock(&dev->stats.access_lock);
1112 data[i] = p[i];
1113 }
1114
1115 usb_autopm_put_interface(dev->intf);
1116} 1269}
1117 1270
1118static void lan78xx_get_wol(struct net_device *netdev, 1271static void lan78xx_get_wol(struct net_device *netdev,
@@ -2095,6 +2248,32 @@ static int lan78xx_reset(struct lan78xx_net *dev)
2095 return 0; 2248 return 0;
2096} 2249}
2097 2250
2251static void lan78xx_init_stats(struct lan78xx_net *dev)
2252{
2253 u32 *p;
2254 int i;
2255
2256 /* initialize for stats update
2257 * some counters are 20bits and some are 32bits
2258 */
2259 p = (u32 *)&dev->stats.rollover_max;
2260 for (i = 0; i < (sizeof(dev->stats.rollover_max) / (sizeof(u32))); i++)
2261 p[i] = 0xFFFFF;
2262
2263 dev->stats.rollover_max.rx_unicast_byte_count = 0xFFFFFFFF;
2264 dev->stats.rollover_max.rx_broadcast_byte_count = 0xFFFFFFFF;
2265 dev->stats.rollover_max.rx_multicast_byte_count = 0xFFFFFFFF;
2266 dev->stats.rollover_max.eee_rx_lpi_transitions = 0xFFFFFFFF;
2267 dev->stats.rollover_max.eee_rx_lpi_time = 0xFFFFFFFF;
2268 dev->stats.rollover_max.tx_unicast_byte_count = 0xFFFFFFFF;
2269 dev->stats.rollover_max.tx_broadcast_byte_count = 0xFFFFFFFF;
2270 dev->stats.rollover_max.tx_multicast_byte_count = 0xFFFFFFFF;
2271 dev->stats.rollover_max.eee_tx_lpi_transitions = 0xFFFFFFFF;
2272 dev->stats.rollover_max.eee_tx_lpi_time = 0xFFFFFFFF;
2273
2274 lan78xx_defer_kevent(dev, EVENT_STAT_UPDATE);
2275}
2276
2098static int lan78xx_open(struct net_device *net) 2277static int lan78xx_open(struct net_device *net)
2099{ 2278{
2100 struct lan78xx_net *dev = netdev_priv(net); 2279 struct lan78xx_net *dev = netdev_priv(net);
@@ -2122,6 +2301,8 @@ static int lan78xx_open(struct net_device *net)
2122 } 2301 }
2123 } 2302 }
2124 2303
2304 lan78xx_init_stats(dev);
2305
2125 set_bit(EVENT_DEV_OPEN, &dev->flags); 2306 set_bit(EVENT_DEV_OPEN, &dev->flags);
2126 2307
2127 netif_start_queue(net); 2308 netif_start_queue(net);
@@ -2166,6 +2347,9 @@ int lan78xx_stop(struct net_device *net)
2166{ 2347{
2167 struct lan78xx_net *dev = netdev_priv(net); 2348 struct lan78xx_net *dev = netdev_priv(net);
2168 2349
2350 if (timer_pending(&dev->stat_monitor))
2351 del_timer_sync(&dev->stat_monitor);
2352
2169 phy_stop(net->phydev); 2353 phy_stop(net->phydev);
2170 phy_disconnect(net->phydev); 2354 phy_disconnect(net->phydev);
2171 net->phydev = NULL; 2355 net->phydev = NULL;
@@ -2910,6 +3094,13 @@ static void lan78xx_bh(unsigned long param)
2910 } 3094 }
2911 3095
2912 if (netif_device_present(dev->net) && netif_running(dev->net)) { 3096 if (netif_device_present(dev->net) && netif_running(dev->net)) {
3097 /* reset update timer delta */
3098 if (timer_pending(&dev->stat_monitor) && (dev->delta != 1)) {
3099 dev->delta = 1;
3100 mod_timer(&dev->stat_monitor,
3101 jiffies + STAT_UPDATE_TIMER);
3102 }
3103
2913 if (!skb_queue_empty(&dev->txq_pend)) 3104 if (!skb_queue_empty(&dev->txq_pend))
2914 lan78xx_tx_bh(dev); 3105 lan78xx_tx_bh(dev);
2915 3106
@@ -2984,6 +3175,17 @@ skip_reset:
2984 usb_autopm_put_interface(dev->intf); 3175 usb_autopm_put_interface(dev->intf);
2985 } 3176 }
2986 } 3177 }
3178
3179 if (test_bit(EVENT_STAT_UPDATE, &dev->flags)) {
3180 lan78xx_update_stats(dev);
3181
3182 clear_bit(EVENT_STAT_UPDATE, &dev->flags);
3183
3184 mod_timer(&dev->stat_monitor,
3185 jiffies + (STAT_UPDATE_TIMER * dev->delta));
3186
3187 dev->delta = min((dev->delta * 2), 50);
3188 }
2987} 3189}
2988 3190
2989static void intr_complete(struct urb *urb) 3191static void intr_complete(struct urb *urb)
@@ -3074,6 +3276,15 @@ static const struct net_device_ops lan78xx_netdev_ops = {
3074 .ndo_vlan_rx_kill_vid = lan78xx_vlan_rx_kill_vid, 3276 .ndo_vlan_rx_kill_vid = lan78xx_vlan_rx_kill_vid,
3075}; 3277};
3076 3278
3279static void lan78xx_stat_monitor(unsigned long param)
3280{
3281 struct lan78xx_net *dev;
3282
3283 dev = (struct lan78xx_net *)param;
3284
3285 lan78xx_defer_kevent(dev, EVENT_STAT_UPDATE);
3286}
3287
3077static int lan78xx_probe(struct usb_interface *intf, 3288static int lan78xx_probe(struct usb_interface *intf,
3078 const struct usb_device_id *id) 3289 const struct usb_device_id *id)
3079{ 3290{
@@ -3120,6 +3331,13 @@ static int lan78xx_probe(struct usb_interface *intf,
3120 netdev->watchdog_timeo = TX_TIMEOUT_JIFFIES; 3331 netdev->watchdog_timeo = TX_TIMEOUT_JIFFIES;
3121 netdev->ethtool_ops = &lan78xx_ethtool_ops; 3332 netdev->ethtool_ops = &lan78xx_ethtool_ops;
3122 3333
3334 dev->stat_monitor.function = lan78xx_stat_monitor;
3335 dev->stat_monitor.data = (unsigned long)dev;
3336 dev->delta = 1;
3337 init_timer(&dev->stat_monitor);
3338
3339 mutex_init(&dev->stats.access_lock);
3340
3123 ret = lan78xx_bind(dev, intf); 3341 ret = lan78xx_bind(dev, intf);
3124 if (ret < 0) 3342 if (ret < 0)
3125 goto out2; 3343 goto out2;
@@ -3397,6 +3615,8 @@ int lan78xx_suspend(struct usb_interface *intf, pm_message_t message)
3397 } 3615 }
3398 3616
3399 if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) { 3617 if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) {
3618 del_timer(&dev->stat_monitor);
3619
3400 if (PMSG_IS_AUTO(message)) { 3620 if (PMSG_IS_AUTO(message)) {
3401 /* auto suspend (selective suspend) */ 3621 /* auto suspend (selective suspend) */
3402 ret = lan78xx_read_reg(dev, MAC_TX, &buf); 3622 ret = lan78xx_read_reg(dev, MAC_TX, &buf);
@@ -3457,6 +3677,12 @@ int lan78xx_resume(struct usb_interface *intf)
3457 int ret; 3677 int ret;
3458 u32 buf; 3678 u32 buf;
3459 3679
3680 if (!timer_pending(&dev->stat_monitor)) {
3681 dev->delta = 1;
3682 mod_timer(&dev->stat_monitor,
3683 jiffies + STAT_UPDATE_TIMER);
3684 }
3685
3460 if (!--dev->suspend_count) { 3686 if (!--dev->suspend_count) {
3461 /* resume interrupt URBs */ 3687 /* resume interrupt URBs */
3462 if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags)) 3688 if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags))