Linux wireless drivers development
 help / color / mirror / Atom feed
From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
To: linux-wireless@vger.kernel.org
Cc: Daniel Drake <dsd@gentoo.org>,
	"John W. Linville" <linville@tuxdriver.com>,
	Ulrich Kunitz <kune@deine-taler.de>
Subject: [PATCH 5/6] zd1211rw: don't let zd_mac_config_beacon() run too long from beacon interrupt handler
Date: Mon, 20 Jun 2011 14:42:49 +0300	[thread overview]
Message-ID: <20110620114249.964.31962.stgit@localhost6.localdomain6> (raw)
In-Reply-To: <20110620114228.964.35459.stgit@localhost6.localdomain6>

zd_mac_config_beacon() has only limited time to set up beacon when called from
beacon interrupt handler/worker. So do not let it retry acquiring beacon fifo
semaphore in interrupt handler. Beacon fifo semaphore should not be locked by
firmware anyway at this time, it's only locked when device is using/txing
beacon.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
---
 drivers/net/wireless/zd1211rw/zd_mac.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 0828605..b67c52d 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -143,7 +143,7 @@ static void beacon_enable(struct zd_mac *mac);
 static void beacon_disable(struct zd_mac *mac);
 static void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble);
 static int zd_mac_config_beacon(struct ieee80211_hw *hw,
-				struct sk_buff *beacon);
+				struct sk_buff *beacon, bool in_intr);
 
 static int zd_reg2alpha2(u8 regdomain, char *alpha2)
 {
@@ -404,7 +404,7 @@ int zd_restore_settings(struct zd_mac *mac)
 		if (mac->vif != NULL) {
 			beacon = ieee80211_beacon_get(mac->hw, mac->vif);
 			if (beacon)
-				zd_mac_config_beacon(mac->hw, beacon);
+				zd_mac_config_beacon(mac->hw, beacon, false);
 		}
 
 		zd_set_beacon_interval(&mac->chip, beacon_interval,
@@ -704,7 +704,8 @@ static void zd_mac_free_cur_beacon(struct zd_mac *mac)
 	mutex_unlock(&mac->chip.mutex);
 }
 
-static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
+static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon,
+				bool in_intr)
 {
 	struct zd_mac *mac = zd_hw_mac(hw);
 	int r, ret, num_cmds, req_pos = 0;
@@ -736,6 +737,10 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
 	r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE);
 	if (r < 0)
 		goto release_sema;
+	if (in_intr && tmp & 0x2) {
+		r = -EBUSY;
+		goto release_sema;
+	}
 
 	end_jiffies = jiffies + HZ / 2; /*~500ms*/
 	message_jiffies = jiffies + HZ / 10; /*~100ms*/
@@ -790,7 +795,7 @@ release_sema:
 	end_jiffies = jiffies + HZ / 2; /*~500ms*/
 	ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE);
 	while (ret < 0) {
-		if (time_is_before_eq_jiffies(end_jiffies)) {
+		if (in_intr || time_is_before_eq_jiffies(end_jiffies)) {
 			ret = -ETIMEDOUT;
 			break;
 		}
@@ -1161,7 +1166,7 @@ static void zd_beacon_done(struct zd_mac *mac)
 	 */
 	beacon = ieee80211_beacon_get(mac->hw, mac->vif);
 	if (beacon)
-		zd_mac_config_beacon(mac->hw, beacon);
+		zd_mac_config_beacon(mac->hw, beacon, true);
 
 	spin_lock_irq(&mac->lock);
 	mac->beacon.last_update = jiffies;
@@ -1286,7 +1291,7 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
 
 			if (beacon) {
 				zd_chip_disable_hwint(&mac->chip);
-				zd_mac_config_beacon(hw, beacon);
+				zd_mac_config_beacon(hw, beacon, false);
 				zd_chip_enable_hwint(&mac->chip);
 			}
 		}
@@ -1439,7 +1444,7 @@ static void beacon_watchdog_handler(struct work_struct *work)
 		if (beacon) {
 			zd_mac_free_cur_beacon(mac);
 
-			zd_mac_config_beacon(mac->hw, beacon);
+			zd_mac_config_beacon(mac->hw, beacon, false);
 		}
 
 		zd_set_beacon_interval(&mac->chip, interval, period, mac->type);


  parent reply	other threads:[~2011-06-20 11:42 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-20 11:42 [PATCH 1/6] zd1211rw: fix invalid signal values from device Jussi Kivilinna
2011-06-20 11:42 ` [PATCH 2/6] zd1211rw: make 'handle_rx_packet: invalid, small RX packet' message debug-only Jussi Kivilinna
2011-06-20 11:42 ` [PATCH 3/6] zd1211rw: only update HW beacon if new beacon differs from currect Jussi Kivilinna
2011-07-02 12:34   ` Walter Goldens
2011-07-04 14:37     ` Jussi Kivilinna
2011-06-20 11:42 ` [PATCH 4/6] zd1211rw: handle lost read-reg interrupts Jussi Kivilinna
2011-06-20 11:42 ` Jussi Kivilinna [this message]
2011-06-20 11:42 ` [PATCH 6/6] zd1211rw: detect stalled beacon interrupt faster Jussi Kivilinna

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=20110620114249.964.31962.stgit@localhost6.localdomain6 \
    --to=jussi.kivilinna@mbnet.fi \
    --cc=dsd@gentoo.org \
    --cc=kune@deine-taler.de \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    /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