From: Larry Finger <Larry.Finger@lwfinger.net>
To: John Linville <linville@tuxdriver.com>, netdev@vger.kernel.org
Subject: [PATCH] bcm43xx-softmac: Init, shutdown and restart fixes
Date: Mon, 21 Aug 2006 09:43:44 -0500 [thread overview]
Message-ID: <44E9C6A0.3090107@lwfinger.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 465 bytes --]
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.
Signed-Off-By: Larry Finger <Larry.Finger@lwfinger.net>
===============================
[-- Attachment #2: patch_init --]
[-- Type: text/plain, Size: 5077 bytes --]
index b095f3c..8ba7e0a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -519,6 +519,7 @@ static int bcm43xx_disable_interrupts_sy
return -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_handle
bcm43xx_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_handle
if (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_handle
mutex_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
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
@@ -141,6 +141,9 @@ void bcm43xx_wireless_core_reset(struct
void 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);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
index ece3351..a16400d 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
@@ -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;
next reply other threads:[~2006-08-21 14:43 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-21 14:43 Larry Finger [this message]
2006-08-21 14:52 ` [PATCH] bcm43xx-softmac: Init, shutdown and restart fixes Michael Buesch
2006-09-11 18:29 ` John W. Linville
2006-09-11 19:35 ` Larry Finger
2006-09-11 19:36 ` [PATCH] Correct out of sequence initialization step for bcm43xx-softmac Larry Finger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44E9C6A0.3090107@lwfinger.net \
--to=larry.finger@lwfinger.net \
--cc=linville@tuxdriver.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).