bcm43xx-softmac: Init, shutdown and restart fixes
Subsystems (3)
PATCH 1/1 bcm43xx-softmac: Init, shutdown and restart fixes
Hi John,
Please apply this to wireless-2.6.
Larry
--
This fixes various bugs in the init and shutdown code that would lead to lockups and crashes, and is the softmac equivalent of the patches submitted by Michael Buesch for bcm43xx-d80211.
These changes may fix some of the NETDEV WATCHDOG transmit timeouts, but they do not fix all of them, at least not in softmac.
===============================
index b095f3c..8ba7e0a 100644
drivers/net/wireless/bcm43xx/bcm43xx_main.c +22 -17
@@ -519,6 +519,7 @@ static int bcm43xx_disable_interrupts_syreturn -EBUSY ; }bcm43xx_interrupt_disable (bcm, BCM43xx_IRQ_ALL); +bcm43xx_read32 (bcm, BCM43xx_MMIO_GEN_IRQ_MASK);/* flush */ spin_unlock_irqrestore (&bcm->irq_lock, flags);bcm43xx_synchronize_irq (bcm);
@@ -3150,6 +3157,7 @@ static void bcm43xx_periodic_work_handle/* Periodic work will take a long time, so we want it to * be preemtible. */ +mutex_lock (&bcm->mutex);netif_stop_queue (bcm->net_dev);synchronize_net ();spin_lock_irqsave (&bcm->irq_lock, flags);
@@ -3158,7 +3160,6 @@ static void bcm43xx_periodic_work_handlebcm43xx_pio_freeze_txqueues (bcm); savedirqs =bcm43xx_interrupt_disable (bcm, BCM43xx_IRQ_ALL);spin_unlock_irqrestore (&bcm->irq_lock, flags); -mutex_lock (&bcm->mutex);bcm43xx_synchronize_irq (bcm); }else {/* Periodic work should take short time, so we want low
@@ -3172,13 +3173,11 @@ static void bcm43xx_periodic_work_handleif (badness >BADNESS_LIMIT ) {spin_lock_irqsave (&bcm->irq_lock, flags); -if (likely (bcm43xx_status (bcm) == BCM43xx_STAT_INITIALIZED)) { -tasklet_enable (&bcm->isr_tasklet); -bcm43xx_interrupt_enable (bcm, savedirqs); -if (bcm43xx_using_pio (bcm)) -bcm43xx_pio_thaw_txqueues (bcm); -bcm43xx_mac_enable (bcm); - } +tasklet_enable (&bcm->isr_tasklet); +bcm43xx_interrupt_enable (bcm, savedirqs); +if (bcm43xx_using_pio (bcm)) +bcm43xx_pio_thaw_txqueues (bcm); +bcm43xx_mac_enable (bcm);netif_wake_queue (bcm->net_dev); }mmiowb ();
@@ -3186,12 +3185,12 @@ static void bcm43xx_periodic_work_handlemutex_unlock (&bcm->mutex); } -static void bcm43xx_periodic_tasks_delete (struct bcm43xx_private *bcm) +void bcm43xx_periodic_tasks_delete (struct bcm43xx_private *bcm) {cancel_rearming_delayed_work (&bcm->periodic_work); } -static void bcm43xx_periodic_tasks_setup (struct bcm43xx_private *bcm) +void bcm43xx_periodic_tasks_setup (struct bcm43xx_private *bcm) {struct work_struct *work = &(bcm->periodic_work);
@@ -3537,11 +3536,10 @@ static int bcm43xx_init_board(struct bcm err =bcm43xx_select_wireless_core (bcm,-1 );if (err) goto err_crystal_off; - -bcm43xx_periodic_tasks_setup (bcm); err =bcm43xx_sysfs_register (bcm);if (err) goto err_wlshutdown; +bcm43xx_periodic_tasks_setup (bcm); err =bcm43xx_rng_init (bcm);if (err) goto err_sysfs_unreg;
@@ -3965,6 +3963,7 @@ static int bcm43xx_net_stop(struct net_d err =bcm43xx_disable_interrupts_sync (bcm);assert (!err);bcm43xx_free_board (bcm); +flush_scheduled_work ();return 0 ; }
@@ -4115,11 +4115,16 @@ static void bcm43xx_chip_reset(void *_bc {struct bcm43xx_private *bcm = _bcm;struct bcm43xx_phyinfo *phy; -int err; +int err = -ENODEV ;mutex_lock (&(bcm)->mutex); - phy =bcm43xx_current_phy (bcm); - err =bcm43xx_select_wireless_core (bcm, phy->type); +if (bcm43xx_status (bcm) == BCM43xx_STAT_INITIALIZED) { +bcm43xx_periodic_tasks_delete (bcm); + phy =bcm43xx_current_phy (bcm); + err =bcm43xx_select_wireless_core (bcm, phy->type); +if (!err) +bcm43xx_periodic_tasks_setup (bcm); + }mutex_unlock (&(bcm)->mutex); printk(KERN_ERR PFX "Controller restart%s\n",
@@ -4128,11 +4133,12 @@ static void bcm43xx_chip_reset(void *_bc/* Hard-reset the chip. * This can be called from interrupt or process context. +* bcm->irq_lock must be locked. */ void bcm43xx_controller_restart (struct bcm43xx_private *bcm,const char *reason) { -assert (bcm43xx_status (bcm) == BCM43xx_STAT_INITIALIZED); -bcm43xx_set_status (bcm, BCM43xx_STAT_RESTARTING); +if (bcm43xx_status (bcm) != BCM43xx_STAT_INITIALIZED) +return ; printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);INIT_WORK (&bcm->restart_work, bcm43xx_chip_reset, bcm);schedule_work (&bcm->restart_work);
index 505c86e..f763571 100644
drivers/net/wireless/bcm43xx/bcm43xx_main.h +3 -0
@@ -141,6 +141,9 @@ void bcm43xx_wireless_core_reset(structvoid bcm43xx_mac_suspend (struct bcm43xx_private *bcm);void bcm43xx_mac_enable (struct bcm43xx_private *bcm); +void bcm43xx_periodic_tasks_delete (struct bcm43xx_private *bcm); +void bcm43xx_periodic_tasks_setup (struct bcm43xx_private *bcm); +void bcm43xx_controller_restart (struct bcm43xx_private *bcm,const char *reason);int bcm43xx_sprom_read (struct bcm43xx_private *bcm,u16 *sprom);
drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +3 -0
@@ -333,8 +333,11 @@ static ssize_t bcm43xx_attr_phymode_stor goto out; } +bcm43xx_periodic_tasks_delete (bcm);mutex_lock (&(bcm)->mutex); err =bcm43xx_select_wireless_core (bcm, phytype); +if (!err) +bcm43xx_periodic_tasks_setup (bcm);mutex_unlock (&(bcm)->mutex);if (err == -ESRCH ) err = -ENODEV ;
Quoted 15 lines · Larry Finger
Hi John,
Please apply this to wireless-2.6.
Larry
--
This fixes various bugs in the init and shutdown code that would lead to lockups and crashes, and is the softmac equivalent of the patches submitted by Michael Buesch for bcm43xx-d80211.
These changes may fix some of the NETDEV WATCHDOG transmit timeouts, but they do not fix all of them, at least not in softmac.
Quoted 3 lines
Signed-off-by Larry Finger <[email protected]>===============================
Next time please inline the patch.
drivers/net/wireless/bcm43xx/bcm43xx_main.c static int bcm43xx_init_board(struct bcm · line 3545
Quoted 13 lines
drivers/net/wireless/bcm43xx/bcm43xx_main.c +1
-2@@ -3537,11 +3536,10 @@ static int bcm43xx_init_board(struct bcm err = bcm43xx_select_wireless_core(bcm, -1); if (err) goto err_crystal_off; - - bcm43xx_periodic_tasks_setup(bcm); err = bcm43xx_sysfs_register(bcm); if (err) goto err_wlshutdown; + bcm43xx_periodic_tasks_setup(bcm); err = bcm43xx_rng_init(bcm); if (err) goto err_sysfs_unreg;
Either move bcm43xx_periodic_tasks_setup after rng_init, or delete the periodic work again, if rng_init fails.
Signature · 1 line
Greetings Michael.
Quoted 18 lines · Michael Buesch
drivers/net/wireless/bcm43xx/bcm43xx_main.c static int bcm43xx_init_board(struct bcm · line 3545
Quoted 13 lines · Larry Finger
drivers/net/wireless/bcm43xx/bcm43xx_main.c +1
-2@@ -3537,11 +3536,10 @@ static int bcm43xx_init_board(struct bcm err = bcm43xx_select_wireless_core(bcm, -1); if (err) goto err_crystal_off; - - bcm43xx_periodic_tasks_setup(bcm); err = bcm43xx_sysfs_register(bcm); if (err) goto err_wlshutdown; + bcm43xx_periodic_tasks_setup(bcm); err = bcm43xx_rng_init(bcm); if (err) goto err_sysfs_unreg;Either move
bcm43xx_periodic_tasks_setupafterrng_init, or delete the periodic work again, ifrng_initfails.
Larry, will you be posting another patch to account for these comments?
John
Signature · 2 lines
John W. Linville [email protected]
Quoted 4 lines · John W. Linville
Quoted 2 lines
Either move
bcm43xx_periodic_tasks_setupafterrng_init, or delete the periodic work again, ifrng_initfails.Larry, will you be posting another patch to account for these comments?
Yes - coming right after this message.
Larry
PATCH 1/1 Correct out of sequence initialization step for bcm43xx-softmac
In reply to John W. LinvilleJohn,
Please apply the following patch to wireless-2.6. It addresses Michael Buesch's comments, which I seem to have missed, regarding the previous patch entitled "bcm43xx-softmac: Init, shutdown and restart fixes".
My copy of the wireless-2.6 indicates that the original patch has already been applied, thus this one only moves the call to bcm43xx_periodic_tasks_setup.
Larry
===============================
This patch fixes an out of sequence step in the bcm43xx_init_board routine for bcm43xx-softmac.
drivers/net/wireless/bcm43xx/bcm43xx_main.c +1 -1
@@ -3540,13 +3540,13 @@ static int bcm43xx_init_board(struct bcmif (err) goto err_crystal_off; -bcm43xx_periodic_tasks_setup (bcm); err =bcm43xx_sysfs_register (bcm);if (err) goto err_wlshutdown; err =bcm43xx_rng_init (bcm);if (err) goto err_sysfs_unreg; +bcm43xx_periodic_tasks_setup (bcm);/*FIXME: This should be handled by softmac instead. */ schedule_work (&bcm->softmac->associnfo.work);
drivers/net/wireless/bcm43xx/bcm43xx_main.c +1 -1
@@ -3540,13 +3540,13 @@ static int bcm43xx_init_board(struct bcmif (err) goto err_crystal_off; -bcm43xx_periodic_tasks_setup (bcm); err =bcm43xx_sysfs_register (bcm);if (err) goto err_wlshutdown; err =bcm43xx_rng_init (bcm);if (err) goto err_sysfs_unreg; +bcm43xx_periodic_tasks_setup (bcm);/*FIXME: This should be handled by softmac instead. */ schedule_work (&bcm->softmac->associnfo.work);