Commit dde4673b authored by Jussi Kivilinna's avatar Jussi Kivilinna Committed by John W. Linville

zd1211rw: don't let zd_mac_config_beacon() run too long from beacon interrupt handler

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: default avatarJussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c900eff3
...@@ -143,7 +143,7 @@ static void beacon_enable(struct zd_mac *mac); ...@@ -143,7 +143,7 @@ static void beacon_enable(struct zd_mac *mac);
static void beacon_disable(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 void set_rts_cts(struct zd_mac *mac, unsigned int short_preamble);
static int zd_mac_config_beacon(struct ieee80211_hw *hw, 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) static int zd_reg2alpha2(u8 regdomain, char *alpha2)
{ {
...@@ -404,7 +404,7 @@ int zd_restore_settings(struct zd_mac *mac) ...@@ -404,7 +404,7 @@ int zd_restore_settings(struct zd_mac *mac)
if (mac->vif != NULL) { if (mac->vif != NULL) {
beacon = ieee80211_beacon_get(mac->hw, mac->vif); beacon = ieee80211_beacon_get(mac->hw, mac->vif);
if (beacon) 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, zd_set_beacon_interval(&mac->chip, beacon_interval,
...@@ -704,7 +704,8 @@ static void zd_mac_free_cur_beacon(struct zd_mac *mac) ...@@ -704,7 +704,8 @@ static void zd_mac_free_cur_beacon(struct zd_mac *mac)
mutex_unlock(&mac->chip.mutex); 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); struct zd_mac *mac = zd_hw_mac(hw);
int r, ret, num_cmds, req_pos = 0; 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) ...@@ -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); r = zd_ioread32_locked(&mac->chip, &tmp, CR_BCN_FIFO_SEMAPHORE);
if (r < 0) if (r < 0)
goto release_sema; goto release_sema;
if (in_intr && tmp & 0x2) {
r = -EBUSY;
goto release_sema;
}
end_jiffies = jiffies + HZ / 2; /*~500ms*/ end_jiffies = jiffies + HZ / 2; /*~500ms*/
message_jiffies = jiffies + HZ / 10; /*~100ms*/ message_jiffies = jiffies + HZ / 10; /*~100ms*/
...@@ -790,7 +795,7 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) ...@@ -790,7 +795,7 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
end_jiffies = jiffies + HZ / 2; /*~500ms*/ end_jiffies = jiffies + HZ / 2; /*~500ms*/
ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE); ret = zd_iowrite32_locked(&mac->chip, 1, CR_BCN_FIFO_SEMAPHORE);
while (ret < 0) { while (ret < 0) {
if (time_is_before_eq_jiffies(end_jiffies)) { if (in_intr || time_is_before_eq_jiffies(end_jiffies)) {
ret = -ETIMEDOUT; ret = -ETIMEDOUT;
break; break;
} }
...@@ -1161,7 +1166,7 @@ static void zd_beacon_done(struct zd_mac *mac) ...@@ -1161,7 +1166,7 @@ static void zd_beacon_done(struct zd_mac *mac)
*/ */
beacon = ieee80211_beacon_get(mac->hw, mac->vif); beacon = ieee80211_beacon_get(mac->hw, mac->vif);
if (beacon) if (beacon)
zd_mac_config_beacon(mac->hw, beacon); zd_mac_config_beacon(mac->hw, beacon, true);
spin_lock_irq(&mac->lock); spin_lock_irq(&mac->lock);
mac->beacon.last_update = jiffies; mac->beacon.last_update = jiffies;
...@@ -1286,7 +1291,7 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, ...@@ -1286,7 +1291,7 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
if (beacon) { if (beacon) {
zd_chip_disable_hwint(&mac->chip); 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); zd_chip_enable_hwint(&mac->chip);
} }
} }
...@@ -1439,7 +1444,7 @@ static void beacon_watchdog_handler(struct work_struct *work) ...@@ -1439,7 +1444,7 @@ static void beacon_watchdog_handler(struct work_struct *work)
if (beacon) { if (beacon) {
zd_mac_free_cur_beacon(mac); 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); zd_set_beacon_interval(&mac->chip, interval, period, mac->type);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment