Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arcnet: add netif_carrier_on/off for reconnect

The arcnet device has no interrupt to detect if the link has changed
from disconnected to connected. This patch adds an timer to toggle the
link detection. The timer will get retriggered as long as the
reconnection interrupts accure. If the recon interrupts hold off
for >1s we define the connection stable again.

Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>

+27
+2
drivers/net/arcnet/arcdevice.h
··· 267 267 struct led_trigger *recon_led_trig; 268 268 char recon_led_trig_name[ARCNET_LED_NAME_SZ]; 269 269 270 + struct timer_list timer; 271 + 270 272 /* 271 273 * Buffer management: an ARCnet card has 4 x 512-byte buffers, each of 272 274 * which can be used for either sending or receiving. The new dynamic
+25
drivers/net/arcnet/arcnet.c
··· 381 381 dev->flags = IFF_BROADCAST; 382 382 } 383 383 384 + static void arcnet_timer(unsigned long data) 385 + { 386 + struct net_device *dev = (struct net_device *)data; 387 + 388 + if (!netif_carrier_ok(dev)) { 389 + netif_carrier_on(dev); 390 + netdev_info(dev, "link up\n"); 391 + } 392 + } 393 + 384 394 struct net_device *alloc_arcdev(const char *name) 385 395 { 386 396 struct net_device *dev; ··· 402 392 struct arcnet_local *lp = netdev_priv(dev); 403 393 404 394 spin_lock_init(&lp->lock); 395 + init_timer(&lp->timer); 396 + lp->timer.data = (unsigned long) dev; 397 + lp->timer.function = arcnet_timer; 405 398 } 406 399 407 400 return dev; ··· 503 490 lp->hw.intmask(dev, lp->intmask); 504 491 arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__); 505 492 493 + netif_carrier_off(dev); 506 494 netif_start_queue(dev); 495 + mod_timer(&lp->timer, jiffies + msecs_to_jiffies(1000)); 507 496 508 497 arcnet_led_event(dev, ARCNET_LED_EVENT_OPEN); 509 498 return 0; ··· 522 507 struct arcnet_local *lp = netdev_priv(dev); 523 508 524 509 arcnet_led_event(dev, ARCNET_LED_EVENT_STOP); 510 + del_timer_sync(&lp->timer); 511 + 525 512 netif_stop_queue(dev); 513 + netif_carrier_off(dev); 526 514 527 515 /* flush TX and disable RX */ 528 516 lp->hw.intmask(dev, 0); ··· 926 908 927 909 arc_printk(D_RECON, dev, "Network reconfiguration detected (status=%Xh)\n", 928 910 status); 911 + if (netif_carrier_ok(dev)) { 912 + netif_carrier_off(dev); 913 + netdev_info(dev, "link down\n"); 914 + } 915 + mod_timer(&lp->timer, jiffies + msecs_to_jiffies(1000)); 916 + 929 917 arcnet_led_event(dev, ARCNET_LED_EVENT_RECON); 930 918 /* MYRECON bit is at bit 7 of diagstatus */ 931 919 if (diagstatus & 0x80) ··· 983 959 lp->num_recons = lp->network_down = 0; 984 960 985 961 arc_printk(D_DURING, dev, "not recon: clearing counters anyway.\n"); 962 + netif_carrier_on(dev); 986 963 } 987 964 988 965 if (didsomething)