hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/arcnet/arcnet.c
....@@ -387,10 +387,44 @@
387387 struct arcnet_local *lp = from_timer(lp, t, timer);
388388 struct net_device *dev = lp->dev;
389389
390
- if (!netif_carrier_ok(dev)) {
390
+ spin_lock_irq(&lp->lock);
391
+
392
+ if (!lp->reset_in_progress && !netif_carrier_ok(dev)) {
391393 netif_carrier_on(dev);
392394 netdev_info(dev, "link up\n");
393395 }
396
+
397
+ spin_unlock_irq(&lp->lock);
398
+}
399
+
400
+static void reset_device_work(struct work_struct *work)
401
+{
402
+ struct arcnet_local *lp;
403
+ struct net_device *dev;
404
+
405
+ lp = container_of(work, struct arcnet_local, reset_work);
406
+ dev = lp->dev;
407
+
408
+ /* Do not bring the network interface back up if an ifdown
409
+ * was already done.
410
+ */
411
+ if (!netif_running(dev) || !lp->reset_in_progress)
412
+ return;
413
+
414
+ rtnl_lock();
415
+
416
+ /* Do another check, in case of an ifdown that was triggered in
417
+ * the small race window between the exit condition above and
418
+ * acquiring RTNL.
419
+ */
420
+ if (!netif_running(dev) || !lp->reset_in_progress)
421
+ goto out;
422
+
423
+ dev_close(dev);
424
+ dev_open(dev, NULL);
425
+
426
+out:
427
+ rtnl_unlock();
394428 }
395429
396430 static void arcnet_reply_tasklet(unsigned long data)
....@@ -434,7 +468,7 @@
434468
435469 ret = sock_queue_err_skb(sk, ackskb);
436470 if (ret)
437
- kfree_skb(ackskb);
471
+ dev_kfree_skb_irq(ackskb);
438472
439473 local_irq_enable();
440474 };
....@@ -452,11 +486,24 @@
452486 lp->dev = dev;
453487 spin_lock_init(&lp->lock);
454488 timer_setup(&lp->timer, arcnet_timer, 0);
489
+ INIT_WORK(&lp->reset_work, reset_device_work);
455490 }
456491
457492 return dev;
458493 }
459494 EXPORT_SYMBOL(alloc_arcdev);
495
+
496
+void free_arcdev(struct net_device *dev)
497
+{
498
+ struct arcnet_local *lp = netdev_priv(dev);
499
+
500
+ /* Do not cancel this at ->ndo_close(), as the workqueue itself
501
+ * indirectly calls the ifdown path through dev_close().
502
+ */
503
+ cancel_work_sync(&lp->reset_work);
504
+ free_netdev(dev);
505
+}
506
+EXPORT_SYMBOL(free_arcdev);
460507
461508 /* Open/initialize the board. This is called sometime after booting when
462509 * the 'ifconfig' program is run.
....@@ -587,6 +634,10 @@
587634
588635 /* shut down the card */
589636 lp->hw.close(dev);
637
+
638
+ /* reset counters */
639
+ lp->reset_in_progress = 0;
640
+
590641 module_put(lp->hw.owner);
591642 return 0;
592643 }
....@@ -763,7 +814,7 @@
763814 }
764815
765816 /* Called by the kernel when transmit times out */
766
-void arcnet_timeout(struct net_device *dev)
817
+void arcnet_timeout(struct net_device *dev, unsigned int txqueue)
767818 {
768819 unsigned long flags;
769820 struct arcnet_local *lp = netdev_priv(dev);
....@@ -820,6 +871,9 @@
820871
821872 spin_lock_irqsave(&lp->lock, flags);
822873
874
+ if (lp->reset_in_progress)
875
+ goto out;
876
+
823877 /* RESET flag was enabled - if device is not running, we must
824878 * clear it right away (but nothing else).
825879 */
....@@ -852,11 +906,14 @@
852906 if (status & RESETflag) {
853907 arc_printk(D_NORMAL, dev, "spurious reset (status=%Xh)\n",
854908 status);
855
- arcnet_close(dev);
856
- arcnet_open(dev);
909
+
910
+ lp->reset_in_progress = 1;
911
+ netif_stop_queue(dev);
912
+ netif_carrier_off(dev);
913
+ schedule_work(&lp->reset_work);
857914
858915 /* get out of the interrupt handler! */
859
- break;
916
+ goto out;
860917 }
861918 /* RX is inhibited - we must have received something.
862919 * Prepare to receive into the next buffer.
....@@ -1052,6 +1109,7 @@
10521109 udelay(1);
10531110 lp->hw.intmask(dev, lp->intmask);
10541111
1112
+out:
10551113 spin_unlock_irqrestore(&lp->lock, flags);
10561114 return retval;
10571115 }